指令的绑定功能中的范围更改未反映出来

时间:2015-06-22 03:06:44

标签: javascript angularjs

我有一个带有删除按钮指令的待办事项列表,如<,p>

enter image description here

然后,当我点击垃圾按钮时,视图没有使用新的待办事项刷新。我使用scope.$apply()来强制摘要周期,但它仍无法正常工作

HTML code,

<div ng-controller="todoCtrl">
   <ul>
      <li ng-repeat="todo in todos">
        <i class="fa fa-trash-o fa-lg" sk-del="{{todo}}" todos="todos"></i>{{todo}}
      </li>
   </ul>
</div>

Javascript代码,

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

app.controller('todoCtrl',  function ($scope, $element) {
  $scope.todos = ["eat", "pray", "live"]
})

app.directive("skDel", function(){
  return {
    scope:{
      todos: '='
    },
    link: function(scope, elem, attr){
      elem.bind("click", function(){
        scope.todos = scope.todos.filter(function(el){
          console.log("the return value for todo - " + el + " is " + (el != attr.skDel))
          return el != attr.skDel
        })
        console.log("new set of todos ----" + JSON.stringify(scope.todos))
        scope.$apply()
      })
    }
  }
})

控制台日志,

the return value for todo - eat is false
the return value for todo - pray is true
the return value for todo - live is true
new set of todos ---- ["pray","live"]

3 个答案:

答案 0 :(得分:3)

问题是您要将新对象分配给todos

&#13;
&#13;
var app = angular.module('my-app', [], function() {})

app.controller('todoCtrl', function($scope, $element) {
  $scope.obj = {
    todos: ["eat", "pray", "live"]
  }
})

app.directive("skDel", function() {
  return {
    scope: {
      todos: '='
    },
    link: function(scope, elem, attr) {
      elem.bind("click", function() {
        scope.todos = scope.todos.filter(function(el) {
          console.log("the return value for todo - " + el + " is " + (el != attr.skDel))
          return el != attr.skDel
        })
        console.log("new set of todos ----" + JSON.stringify(scope.todos))

        scope.$apply()
      })
    }
  }
})
&#13;
<link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="my-app">
  <div ng-controller="todoCtrl">
    <ul>
      <li ng-repeat="todo in obj.todos"><i class="fa fa-trash-o fa-lg" sk-del="{{todo}}" todos="obj.todos"></i>{{todo}}</li>
    </ul>
    <pre>{{todos | json}}</pre>
  </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

scope.todos = scope.todos.filter()

.filter创建一个新数组,因此scope.todos指向新数组而不是指向父作用域(Controller)scope.todos。并且您的视图仍在侦听父级(控制器)scope,因此视图不会更新。

但是,您可以使用.splice,它不会更改子范围的引用。因此,当您更新子范围时,父级$scope.todos也会得到更新,因为父级和父级之间存在双向绑定。子。

将$ index添加到ngRepeat指令。

<li ng-repeat="todo in todos track by $index">
    <i class="fa fa-trash-o fa-lg" sk-del="{{todo}}" todos="todos" index={{$index}}></i>{{todo}}
</li>

你的指令bind handlder应如下所示。

  elem.bind("click", function(){

    scope.todos.splice(attr.index,1);
    scope.$apply();

  });

答案 2 :(得分:0)

主要问题是&#39; false&#39;仍然是一个值,仍将返回视图上的输出。可能是array.filter的替代array.splice,它只是从数组中删除该项。

我创造了一个证明这一点的小提琴:

http://jsfiddle.net/spanndemic/79cqxxby/

相关的更改是代码的这一部分:

HTML:

<div ng-app="app">
  <div ng-controller="todoCtrl">
     <ul>
        <li ng-repeat="todo in todos">
          <i class="fa fa-trash-o fa-lg" sk-del="{{todo}}" todos="todos" data-index="{{$index}}"></i>{{todo}}
        </li>
     </ul>
  </div>
</div>

JS:

var app = angular.module('app',  [])
.controller('todoCtrl',  function ($scope, $element) {
  $scope.todos = ["eat", "pray", "live"]
})

app.directive("skDel", function(){
  return {
    scope:{
      todos: '='
    },
    link: function(scope, elem, attr){
      elem.bind("click", function(){

        scope.todos.splice(attr.index, 1);

        console.log("new set of todos ----" + JSON.stringify(scope.todos));

        scope.$apply();

      })

    }
  }
})