2017-04-09 51 views
0

我正在使用模態來顯示呈現給用戶的表單。形式是具有的onSave和onCancel方法的所有組件AngularJS組件不動態傳遞事件的動態編譯

bindings: { 
     entity: '<', 
     readOnly: '<', 
     onSave: '&', 
     onCancel: '&' 
    }, 

欲通入一個模態的形式的標籤存在於模態,然後通過由該組件的的onSave/onCancel事件返回給參數將返回給調用者的模式。要做到這一點,我把那臺組件的屬性的指令,然後運行它通過$編譯方法來生成它:

function link(scope, elem, attrs) { 
     if (scope.formType != null && scope.formType != '') { 
      var objString = "<" + scope.formType + " "; //create beginning tag 
      objString += "entity='assignedEntity' read-only='readOnly' "; 
      objString += "on-save='onSave(entity)' on-cancel='onCancel(entity)'>"; 
      objString += "</" + scope.formType + ">"; //add end tag 

      var obj = $compile(objString)(scope); 

      elem.append(obj); 
     } 
    }; 

    return { 
     restrict: 'E', 
     scope: { 
      formType: '=', 
      onSave: '&', 
      onCancel: '&', 
      assignedEntity: '<', 
      readOnly: '<' 
     }, 
     link: link 
    } 

我然後調用指令,從一個普通模式通過相應的屬性盒如下:

<form-generator 
       form-type="vm.ui.properties.formType" 
       on-save="vm.ok(entity)" 
       on-cancel="vm.cancel(entity)" 
       assigned-entity="vm.returnItem.entity" 
       read-only="vm.ui.properties.readOnly"> 
      </form-generator> 

這成功地生成指定的表單組件,並將每個屬性的正確值傳遞給表單組件。我的問題是,當組件拋出onSave或onCancel事件時,模態控制器正在接收事件(vm.ok或vm.cancel被調用),但傳遞給這些事件的參數不會隨呼叫傳遞。傳遞給vm.ok和vm.cancel的屬性始終未定義。

從組件,我調用的onSave/onCancel方法是這樣的:

ctrl.onSave({ 
      entity: ctrl.entity 
     }); 

,我已經驗證ctrl.entity事實上確實有它的價值。

對於爲什麼傳回給調用樹的參數爲什麼沒有定義它到達模態控制器的時間?

我創造了這個plunkr以幫助確定我有問題:Example

+0

除另有規定外,其組件控制器綁定到'$ ctrl',不'ctrl'。有關更多信息,請參閱[AngularJS開發人員指南 - 組件 - 比較表](https://docs.angularjs.org/guide/component#comparison-between-directive-definition-and-component-definition)。 – georgeawg

+0

是的。我在模板上使用$ ctrl。我在與組件關聯的控制器中分配var ctrl = this。 ctrl.entity具有正確的值(從模板傳遞給它的值),而ctrl.onSave確實調用與該方法關聯的函數。它只是不會將該對象{entity:ctrl.entity}傳遞給父控制器。 – JakeHova

+0

當您提出有關由您的代碼導致的問題的問題時,如果您提供可用於重現問題的代碼,您將得到更好的答案。請參見[如何創建最小,完整和可驗證示例](http://stackoverflow.com/help/mcve)。 – georgeawg

回答

1

請檢查代碼,有點調試的似乎後,像你剛纔忘了實體附加爲監聽功能的一部分點擊$事件。這裏是工作plunker

(function() { 

    var directiveID = "formGenerator"; 

    angular.module('app').directive(directiveID, ['$compile', FormGenerator]); 

    function FormGenerator($compile) { 

    function link(scope, elem, attrs) { 
     console.log(scope, elem, attrs); 
     if (scope.formType !== null && scope.formType !== '') { 
     var objString = "<" + scope.formType + " "; //create beginning tag 
     //PLEASE TAKE A LOOK HERE, WE'RE EXPECTING THE EVENT TO PROPOGATE TO THE PARENT CONTROLLER 
     //so we take into account the event on-save, the same would have to be done for on-cancel 
     objString += "on-save='onFormSave($event)' on-cancel='onFormCancel(entity)'>"; 
     objString += "</" + scope.formType + ">"; //add end tag 

     var obj = $compile(objString)(scope); 

     elem.append(obj); 
     } 
    } 

    return { 
     restrict: 'E', 
     scope: { 
     formType: '=', 
     onFormSave: '&', 
     onFormCancel: '&' 
     }, 
     link: link 
    } 
    } 
})(); 




(function() { 
    var componentID = "testForm"; 

    var app = angular.module("app"); 

    function TestFormController() { 
    var ctrl = this; 

    ctrl.entity = { 
     name: "this is the entity passed up" 
    }; 

    ctrl.save = function(event) { 
     console.log(event); 
     console.log("In component: " + ctrl.entity.name); 
     ctrl.onSave({ 
     //AND ON SAVE, we make the this controllers model-properties which you'd like to pass on a part of the event. 
     $event: { 
      entity: ctrl.entity 
     } 
     }); 
    }; 

    ctrl.cancel = function() { 
     ctrl.onCancel({ 
     entity: ctrl.entity 
     }); 
    }; 
    } 

    app.component(componentID, { 
    bindings: { 
     onSave: '&', 
     onCancel: '&' 
    }, 
    //Here also we pass the $event to function 
    template: '<h1> This is a test</h1><button type="button" ng-click="$ctrl.save($event);">Save</button>', 
    controller: TestFormController 
    }) 

}()); 
+1

嘆息,是的,就是這樣。我完全忘記了$事件傳遞。謝謝。 – JakeHova