2017-04-17 3 views
0

symfony 3 프로젝트에서 knockout.js를 사용하여 아약스를 통해 제출하려는 양식을 만들었습니다. 그러나 일부에서는 브라우저가 아약스를 통해 수행하는 대신 액션으로 리디렉션됩니다.Symfony 녹아웃 : 바인딩 핸들러를 수신 할 수없는 사용자 정의 바인딩 핸들

내가 app/FosUserBundle/views/Registration/register.html.twig라는 이름의 파일을 아약스와 함께 제출할 양식은 다음과 같습니다

define(['knockout','jquery'],function(ko,$) 
{ 

    ko.bindingHandlers.formSubmitAjax={ 
    init: function(element, valueAccessor, allBindingsAccessor) 
    { 
     var callbacks=valueAccessor(); 

     var action=$(element).attr('action'); 
     var method=$(element).attr('method'); 
     var dataType=(callbacks && callbacks['type'])?callbacks['type']:'json';//By default use Json 


     $(element).submit(function(e) 
     { 
     e.preventDefault(); 
     var form_data= $(this).serialize(); 

     $.ajax({ 
      'method':method, 
      'data':form_data, 
      'url':action, 
      'beforeSend':function() 
      { 
      if(typeof callbacks['beforeSend'] === 'function') callbacks['beforeSend'](); 
      }, 
      'success':function(data,textStatus,jqXHR) 
      { 
      if(typeof callbacks['success'] === 'function') callbacks['success'](data,textStatus,jqXHR); 
      }, 
      'error':function(jqXHR,textStatus,errorThrown) 
      { 
      if(typeof callbacks['error'] === 'function') callbacks['error'](jqXHR,textStatus,errorThrown); 
      }, 
      'complete':function(jqXHR,textStatus) 
      { 
      if(typeof callbacks['always'] === 'function') callbacks['always'](jqXHR,textStatus); 
      } 
     }); 
     }); 
    } 
    }; 

}) 

이 양식 :

{% extends "FOSUserBundle::layout.html.twig" %} 

{% block fos_user_content %} 

    {% form_theme form '::themes/register-form-theme.html.twig' %} 
    {% trans_default_domain 'FOSUserBundle' %} 

<div class="container" data-bind="with:registerVm"> 
    <div class="register-box"> 
    <div class="register-logo"> 
     <h1>PhotoShare!</h1> 
    </div> 
    <div class="register-box-body"> 
     <p class="login-box-msg">Register a new membership</p> 
     {{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register'),'attr':{'data-bind':'formSubmitAjax:\{\'success\':registerComplete\}'}}) }} 
     {{ form_widget(form) }} 
     <div class="row"> 
      <div class="col-xs-4"> 
      <input type="submit" class="btn btn-primary btn-block btn-flat" value="{{ 'registration.submit'|trans }}" /> 
      </div> 
     </div> 
     {{ form_end(form) }} 
    </div> 
</div> 

{% endblock fos_user_content %} 

양식은 다음 knockout.js 사용자 정의 바인딩 처리기를 사용할 필요가 이 나뭇 가지 템플릿의 pager.js를 통해 렌더링됩니다.

{% extends "base.html.twig" %} 

{% set classes=''%} 

{% block javascriptsHeader %} 
    <script src="{{asset('assets/vendor/require.js')}}" data-main="{{path('main_javascript')}}" ></script> 
{% endblock %} 

{% block stylesheets %} 
    {{ parent() }} 
    <link rel="stylesheet" type="text.css" href="{{ asset('assets/vendor/xeditable/css/bootstrap-editable.css') }}" > 
    <style> 
    #message-area{ 
     z-index:9999; 
    } 
    .page{ 
     min-height:100%; 
     min-width:100%; 
    } 
    </style> 
{% endblock %} 

{% block body %} 
    <div id="message-area"></div> 
    <div class="hold-transition register-page page" data-bind="page: {id:'register', title:'Register', role:'start', sourceOnShow: '{{ path('fos_user_registration_register') }}', withOnShow:function(a){registerVm.init();},with:registerVm}"></div> 
{% endblock %} 

<!DOCTYPE html> 
<html> 
    <head> 
     <meta charset="UTF-8" /> 
     <title>{% block title %}Welcome!{% endblock %}</title> 
     <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
     <meta name="viewport" content="width=device-width, initial-scale=1"> 

     {% block stylesheets %} 
      <link rel="stylesheet" type="text/css" href="{{asset('assets/vendor/bootstrap/css/bootstrap.css')}}" > 
      <link rel="stylesheet" type="text/css" href="{{asset('assets/vendor/adminlte/adminlte.css')}}" > 
      <link rel="stylesheet" type="text/css" href="{{asset('assets/vendor/adminlte/skin-blue.css')}}" > 
     {% endblock %} 
     <link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" /> 

     {% block javascriptsHeader %} 
     {% endblock %} 

    </head> 
    <body class="{{ classes }}"> 
     {% block body %} 
     {% endblock body %} 

     {% block javascriptsFooter %} 

     {% endblock javascriptsFooter %} 
    </body> 
</html> 

내가 다음 require.js 템플릿을 통해 그것을 모든 필요한 자바 스크립트 렌더링 : 녹아웃

requirejs.config({ 
    baseUrl:'{{asset('assets')}}', 
    paths:{ 
    'text':'{{ asset('assets/vendor/text') }}', 

    'knockout':'{{ asset('assets/vendor/knockout') }}', 
    'pager':"{{asset('assets/vendor/pager')}}", 
    'bootstrap':"{{asset('assets/vendor/bootstrap/js/bootstrap')}}", 

    'jquery':"{{asset('assets/vendor/jquery')}}", 
    'jquery_ui':"{{ asset('assets/vendor/jquery-ui') }}", 

    'xeditable_bootstrap':"{{ asset('assets/vendor/xeditable/xeditable') }}", 
    'ko_xeditable':"{{ asset('assets/vendor/knockout/knockout.x-editable') }}", 

    'jquery-fileupload':"{{ asset('assets/vendor/jquery_fileupload/jquery.fileupload') }}", 
    'jquery-iframe':"{{ asset('assets/vendor/jquery_fileupload/jquery.iframe-transport') }}", 
    'jquery-ui-widget':"{{ asset('assets/vendor/jquery_fileupload/jquery.ui.widget') }}", 

    'masterViewModel':"{{ asset('assets/js/viewModels/masterViewModel') }}", 
    'registerViewModel':"{{ asset('assets/js/viewModels/registerPageViewModel') }}", 
    {% block Viewmodels %} 
    {% endblock %} 

    'formPost':"{{ asset('assets/js/bindingHandlers/formPost') }}", 

    'compMessage':"{{ asset('assets/js/components/message/message') }}", 
    'extBooleanToggle':'assets/js/extenders/booleanToggle', 
    }, 
    shim:{ 
    'pager': ['jquery', 'knockout'], 
    'jquery_ui':['jquery'], 
    'bootstrap':['jquery'], 
    'xeditable_bootstrap':['jquery-ui','bootstrap'], 
    'ko_xeditable':['xeditable_bootstrap'], 
    'jquery-fileupload':['jquery-iframe','jquery-ui-widget'], 
    'jquery-ui-widget':['jquery_ui'],//Jquery_ui already load jquery 
    'jquery-iframe':['jquery'] 
    {% block CustomShim %} 
    {% endblock %} 
    }, 
    waitSeconds: 200, 
}); 

define(['jquery','knockout','pager','masterViewModel','bootstrap'],function($,ko,pager,masterViewModel) 
{ 
    $(document).ready(function(){ 
     pager.extendWithPage(masterViewModel); 
     ko.applyBindings(masterViewModel); 
     pager.start(); 
    }); 
}); 

그리고 마스터 뷰 모델과 IS가 가지고와 pager.js 초기화 다음과 같은 기본 템플릿을 경향이있다 다음

define(['knockout','jquery','registerViewModel'],function(ko,$,registervm){ 

    function MasterViewModel() 
    { 
     var self=this;  
     self.registerVm=new registervm(self); 
    } 

    return new MasterViewModel(); 
}) 

는 동료가 formSubmitAjax가되지 호출되는 않는 이유 어떤 아이디어가 있습니까?

+0

너무 일찍 바인딩을 적용 할 수 있습니다, 나는 당신의'formSubmitAjax'을 테스트했고 잘 동작합니다 (https://jsfiddle.net/ddv4vubd/). 그래서'$ (document) .ready' 안에'setTimeout'을 시도해보십시오. 문제가 있는지 확인하십시오. – Jag

+0

이미 시간 초과를 설정했지만 여전히 문제가 남아 있습니다. –

답변

0

은 내가 require.js에서 다음 shim 섹션을 넣어 마치 마법처럼 일했다 :

'masterViewModel':['registerViewModel'], 
'registerViewModel':['formPost'] 

followimg에 결과

requirejs.config({ 
    baseUrl:'{{asset('assets')}}', 
    paths:{ 
    'text':'{{ asset('assets/vendor/text') }}', 

    'knockout':'{{ asset('assets/vendor/knockout') }}', 
    'pager':"{{asset('assets/vendor/pager')}}", 
    'bootstrap':"{{asset('assets/vendor/bootstrap/js/bootstrap')}}", 

    'jquery':"{{asset('assets/vendor/jquery')}}", 
    'jquery_ui':"{{ asset('assets/vendor/jquery-ui') }}", 

    'xeditable_bootstrap':"{{ asset('assets/vendor/xeditable/xeditable') }}", 
    'ko_xeditable':"{{ asset('assets/vendor/knockout/knockout.x-editable') }}", 

    'jquery-fileupload':"{{ asset('assets/vendor/jquery_fileupload/jquery.fileupload') }}", 
    'jquery-iframe':"{{ asset('assets/vendor/jquery_fileupload/jquery.iframe-transport') }}", 
    'jquery-ui-widget':"{{ asset('assets/vendor/jquery_fileupload/jquery.ui.widget') }}", 

    'masterViewModel':"{{ asset('assets/js/viewModels/masterViewModel') }}", 
    'registerViewModel':"{{ asset('assets/js/viewModels/registerPageViewModel') }}", 
    {% block Viewmodels %} 
    {% endblock %} 

    'formPost':"{{ asset('assets/js/bindingHandlers/formPost') }}", 
    //'debug':"{{ asset('assets/js/bindingHandlers/debug') }}", 

    'compMessage':"{{ asset('assets/js/components/message/message') }}", 
    'extBooleanToggle':'assets/js/extenders/booleanToggle', 
    }, 
    shim:{ 
    'pager': ['jquery', 'knockout'], 
    'jquery_ui':['jquery'], 
    'bootstrap':['jquery'], 
    'xeditable_bootstrap':['jquery-ui','bootstrap'], 
    'ko_xeditable':['xeditable_bootstrap'], 
    'jquery-fileupload':['jquery-iframe','jquery-ui-widget'], 
    'jquery-ui-widget':['jquery_ui'],//Jquery_ui already load jquery 
    'jquery-iframe':['jquery'], 
    'masterViewModel':['registerViewModel'], 
    'registerViewModel':['formPost'] 
    {% block CustomShim %} 
    {% endblock %} 
    }, 
    waitSeconds: 200, 
}); 

define(['jquery','knockout','pager','masterViewModel','bootstrap'],function($,ko,pager,masterViewModel) 
{ 
    $(document).ready(function(){ 
      pager.extendWithPage(masterViewModel); 
      ko.applyBindings(masterViewModel); 
      pager.start(); 
    }); 
}); 

을 main.js.twig 그리고 매력처럼 일했다! !!

0

ko.applyBindings을 호출하기 전에 바인딩 처리기가로드되었는지 확인해야합니다. 이런 식으로 뭔가 :

define(['jquery','knockout','pager','masterViewModel','bootstrap', 'formPost'], function($,ko,pager,masterViewModel) 
{ 
    $(document).ready(function(){ 
     pager.extendWithPage(masterViewModel); 
     ko.applyBindings(masterViewModel); 
     pager.start(); 
    }); 
}); 
+0

Nope은 여전히 ​​새로 고칩니다. –