具有作用域的指令破坏输入的ngmodel

3

我应该给我的指令什么作用域,才能使输入框显示初始值“Toto”?我不想使用scope:true。

HTML代码:

<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <script>document.write('<base href="' + document.location + '" />');</script>
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
   <input customattr type = "text" ng-model="value.name" />   
</body>
</html>

JS代码:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.value = {"name":"Toto", "id":1};

});

    app.directive('customattr', function () {
      return {
          restrict: 'A',
          scope: {
          },
          link: function (scope, element, attrs) {

          } 
      }; 
    });

在这里查看Plunker: http://plnkr.co/edit/JxWElWhTeBbNpFHS0wYT
1个回答

8

我想这是使用AngularJS指令和作用域经常遇到的问题之一。为了理解以下的解决方案和建议,我们需要了解一个关于AngularJS DOM元素和作用域的事情:

在AngularJS中,任何单个的DOM元素都只与一个作用域相关联。

这意味着我们不能在给定元素上拥有一部分属性与一个作用域配合使用,而另一部分属性则与不同的作用域配合使用。这正是您在plunker中尝试做的事情,其中您期望ng-model属性与一个作用域(由ng-controller指令在<body>元素上定义)配合工作,而customattr则与另一个作用域 - 在指令中创建的隔离作用域配合使用)。

你基本上有两种方法来解决这个问题:

1)使用ng-model="$parent.value.name"来明确地指向ng-model指令到特定的作用域。但这很脆弱而且不明显。

2)从属性指令中删除隔离作用域。作为经验法则,我建议不要在与输入字段(与ng-model结合使用)作为属性指令使用的指令中使用隔离作用域。您仍然可以使用$parse服务获取属性的值。


好的。我明白customattr和ng-model具有不同的作用域,但我想通过在一个变量上使用作用域绑定“=”来逃避这个问题(我不知道应该选择哪个变量)。难道绑定“=”的主要目的不是协调2个不同的作用域吗? 我的主要目的是希望限制作用域,以使我的指令更通用。 - JohnCastle
@JohnCastle 这两个是不同的问题。问题在于,通过使用 scope = {val: '='} 语法,您正在在此 DOM 元素上创建一个新的、隔离的范围,并遇到如上所述的问题。 - pkozlowski.opensource
@JohnCastle 还有一件事 - 如果您能详细说明您的实际用例,也许我可以提出一个解决方案。 - pkozlowski.opensource
是的,使用情况是: 我想制作一个指令,它接收字段中的输入数据,对其进行处理,然后更新ng-model变量。我的主要问题是:我希望能够修改ng-model变量,但我不知道该如何做。如果我知道与输入相关联的作用域变量是“toto”,我可以执行scope.$apply(function() { scope.toto = myVal;}); 但在一般情况下应该怎么做?attrs.$set("ngModel" myVal);似乎行不通。 - JohnCastle
@JohnCastle 好的,我明白了。因此,正确的解决方案与我们正在讨论的内容没有太大关系。应该采用的方法是插入到http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController中。您能否发布另一个问题来描述您的用例?还要指出您想要为给定字段执行什么样的处理。这份文档对您也可能有所帮助:http://docs.angularjs.org/guide/forms - pkozlowski.opensource
我创建了一个新问题:http://stackoverflow.com/questions/16156364/update-scope-with-satellite-data如果你有任何想法,请告诉我。 - JohnCastle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接