ng-repeat 中的指令双向数据绑定不起作用

directive twoway data binding inside ng-repeat is not working

这里我想根据指令范围的变化更新控制器范围值,但是它只能在 ng-repeat 之外工作并且它不能在 ng- 内部工作重复..

HTML

<div ng-app="app">

  <div ng-controller="MainCtrl">
    <div>
      <h3>
    outside repeat
    </h3>
      <br> Name <strong>{{name}}</strong>
      <div class="directive" my-directive name="name"></div>
      <button ng-click="run()">See changes</button>

      <br>
      <br>
      <h3>
    Inside repeat
    </h3>
      <br>
      <div ng-repeat="(k,v) in rawdata">
        {{k}} {{v.key}} Name <strong>{{name}}</strong>
        <div class="directive" my-directive name="name"></div>
        <button ng-click="run()">See changes</button>
        <br>
      </div>
    </div>
  </div>

JS

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

    app.controller("MainCtrl", function($scope) {
      $scope.name = "HappyNewYear2016";
      $scope.run = function() {
        alert($scope.name);
      }

      $scope.rawdata = [{
        key: "event1",
      }, {
        key: "event2",
      }];

    });

    app.directive("myDirective", function() {

      return {
        restrict: "EA",
        scope: {
          name: "="
        },
        template: [
          "<div>",
          "Name : <strong>{{name}}</strong>;  Change name:<input type='text' ng-model='name' /><br/>",
        ].join("")
      };
    });

JSFiddle Link

请帮助我从这个 ngrepeat 中的指令更新控制器值..

基本上问题是控制器内的 $scope.name 与您传递给 ng-repeat 元素内的指令不同,因为 ng-repeat 确实创建了一个子作用域,它是在遍历 rawdata 对象时原型继承自父作用域。


有几种方法可以解决这个问题。

  1. 如果您想通过在 name 之前使用 $parent 注释来解决这个子和父范围相关的问题,这将引用父范围。

Plunkr 在指令中使用 $parent

缺点:-

但过了某个点$parent会让你抓狂。假设如果您有两个或三个子范围层次结构,它将变得像 $parent.$parent.$parent.name 看起来非常奇怪。


  1. 在您的情况下,name 是原始数据类型,因此在创建子作用域时,父作用域的原始数据类型值在子作用域内不可访问。这就是为什么您使用 $parent 来指示名称属于父范围的原因。您可以通过在声明对象时遵循 do annotation 来解决这个问题。这将帮助您通过遵循原型继承使父范围 属性 在子范围内可用。

HTML

<div class="directive" my-directive name="model.name"></div>

代码

$scope.model = {
    name: 'HappyNewYear2016'
};

Plunkr 点符号


  1. 您只需将 run 函数的 name 值传递给 ng-click="run(name)"
  2. 即可解决此问题

Html

<div ng-repeat="(k,v) in rawdata">
    {{k}} {{v.key}} Name <strong>{{name}}</strong>
    <div class="directive" my-directive name="name"></div>
    <button ng-click="run(name)">See changes</button>
    <br>
</div>

代码

$scope.run = function(name) {
    alert(name);
}

  1. 您可以在使用别名声明控制器时使用 controllerAs 语法,并通过别名传递控制器 name 属性。

Working Plunkr

这都是因为原型继承的工作原理,因为范围指令和控制器的模型名称相同。 Child 指令隐藏控制器模型。

与其将控制器模型直接存储为变量,不如将其与 object 一起使用。

$scope.data = {
  name : 'HappyNewYear2016'
}

然后将其用作data.name以在ng-repeat中进行设置。它也会反映在 parent 中。