angularjs – 使用ngModel和普通的ngController而不是指令?

前端之家收集整理的这篇文章主要介绍了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.

2) I have been trying to figure out where ngModelControllers are stored so that I could look at the situation in the debugger but have not been able to find them. When using an ngModel directive should I see these in the scope or parent scope? (Where do they live?!?)

答案取决于您要从哪里访问控制器.

使用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可以看出.

1) Is there some way to use ngModel along with a plain controller to get the effect above?

一旦在指令中有了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.是的,它可能不会被重用,但它确实有助于在代码的各个部分之间强制分离责任.

猜你在找的Angularjs相关文章