angularjs – 使用ngModel和普通的ngController而不是指令?
在我的应用程序中,我想保留对代码的某些部分使用普通控制器的选项 – 而不是为永远不会重复使用的一次性事物创建指令.
在这些情况下,我经常想要从控制器发布一些数据,以便在包含的部分中使用.现在,我知道我可以简单地绑定控制器范围内的项目,但是我想明确指定“模型”位置,以使代码更易于维护和更易于阅读.我想要使??用的是ng-model,因为它将用于自定义指令,但就在我的普通控制器旁边: <div ng-controller="AppController" ng-model='fooModel'> {{fooModel}} </div> 但是,我没有办法在不使用指令和’require’注入的情况下获得对生成的ngModelController的引用. 我知道我可以通过将$attr注入到我的控制器中来轻松地创建自己的属性,并执行以下操作: <div ng-controller="AppController" my-model='fooModel'> {{fooModel}} </div> 在这种情况下,我只需手动获取或解析myModel值,并将我的模型粘贴到该名称下的$scope中.然而,在这种情况下感觉不对 – 我真的只需要一个控制器的“模型”,并且我宁愿不必在ngModel存在时将这个样板添加到每个控制器. (这是事情的原则!) 我的问题是: 1)有没有办法使用ngModel和普通控制器来获得上述效果? 2)我一直在试图找出存储ngModelControllers的位置,这样我就可以查看调试器中的情况但却找不到它们.使用ngModel指令时,我应该在范围或父范围内看到这些吗? (他们住在哪里?!?) 更新:如下面的答案所示,$element.controller()可用于获取控制器.这工作(http://plnkr.co/edit/bZzdLpacmAyKy239tNAO?p=preview)然而,它有点不满意,因为它需要使用$evalAsync.
答案取决于您要从哪里访问控制器. 使用ng-model从元素外部 它在具有ng-model属性的元素和父表单(或ngForm)上都需要“name”属性.所以假设你有一个名为myForm的表单和一个名为myInput的ng-model属性的元素,那么你可以从父作用域访问myFoo的ngModelController作为myForm.myInput.例如,出于调试目的: <p>myFoo: {{myForm.myInput.$modelValue}}<p> <form name="myForm"> <div ng-controller="InnerController" name="myInput" ng-model="model.foo"></div> </form> 从http://plnkr.co/edit/IVTtvIXlBWXGytOEHYbn?p=preview可以看出 从具有ng-model的元素内部 与answer from @pixelbits类似,由于控制器创建的顺序,需要使用$evalAsync,但您也可以使用angular.element.controller函数来检索它: app.controller('InnerController',function($scope,$element) { $scope.$evalAsync(function() { $scope.myModelController = $element.controller('ngModel'); }); }); 在控制器内部使用,以进行调试,如下所示: <div ng-controller="InnerController" ng-model="model.foo"> <p>myFoo: {{myModelController.$modelValue}}<p> </div> 从http://plnkr.co/edit/C7ykMHmd8Be1N1Gl1Auc?p=preview可以看出.
一旦在指令中有了ngModelController,就可以像使用$setViewValue函数使用访问ngModelController的自定义指令一样更改其值: myModelController.$setViewValue('my-new-model-value'); 例如,您可以执行此操作以响应触发ngChange处理程序的用户操作. app.controller('InnerController',$element) { $scope.$evalAsync(function() { $scope.myModelController = $element.controller('ngModel'); }); $scope.$watch('myModelController.$modelValue',function(externalModel) { $scope.localModel = externalModel; }); $scope.changed = function() { $scope.myModelController.$setViewValue($scope.localModel); }; }); 请注意$modelValue上的额外观察者以获取模型的初始值,以及对任何后续更改做出反应. 它可以与模板一起使用,如: {{model.foo}} <div ng-controller="InnerController" ng-model="model.foo"> <p><input type="text" ng-model="localModel" ng-change="changed()"></p> </div> 请注意,这使用ngChange而不是localModel上的观察程序.这是故意的,因此只有当用户与元素交互时才调用$setViewValue,而不是响应来自父作用域的模型更改. 这可以在http://plnkr.co/edit/uknixs6RhXtrqK4ZWLuC?p=preview看到 编辑:如果您想避免使用$evalAsync,可以使用观察者. $scope.$watch(function() { return $element.controller('ngModel'); },function(ngModelController) { $scope.myModelController = ngModelController; }); 见于http://plnkr.co/edit/gJonpzLoVsgc8zB6tsZ1?p=preview 作为旁注,到目前为止,我似乎已经避免了像这样的嵌套普通控制器.我认为如果模板角色的某个部分是通过ngModel来控制变量,那么它是编写小指令的主要候选者,通常使用隔离范围来确保由于范围继承而没有意外的影响,这有明确的API,并使用require来访问ngModelController.是的,它可能不会被重用,但它确实有助于在代码的各个部分之间强制分离责任. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |