【问题标题】:AngularJS : Two way binding inside directivesAngularJS:指令内的两种方式绑定
【发布时间】:2014-03-10 14:11:00
【问题描述】:

我对 Angularjs 比较陌生,我正在编写一个应用程序。该应用程序有一个对象数组,每个对象都有一个称为状态的私有变量。我有两个过滤器,它们根据它们的状态返回这些对象的子集。例如,这两个过滤器对应的状态分别是“NEW”和“OLD”。

接下来,我编写了一个指令,使这些对象形成的 div 可拖动。基本上,指令所做的就是通过双向数据绑定接收对象,然后通过调用相应的方法来改变对象的状态。

问题是,对象状态的变化不会立即更新过滤器。例如,当我将三个 div 拖到另一半时,它们的状态会更新,但过滤器不会。

指令如下:

.directive('draggable', function ($document) {
return {
    scope: {
        bill: '=' // the bill object
    },
    restrict: 'A',
    link: function (scope, element, attr) {
        // do something here
        console.log('bill', scope.bill);
        var startX = 0,
            startY = 0,
            x = 0,
            y = 0,
            sourceX = 0,
            sourceY = 0,
            windowWidth = 0;

        element.on('mousedown', function (event) {
            event.preventDefault();
            startX = event.pageX - x;
            startY = event.pageY - y;
            $document.on('mousemove', mousemove);
            $document.on('mouseup', mouseup);
            windowWidth = $(window).width();
            sourceY = event.pageY;
            sourceX = event.pageX;
        });

        function mousemove(event) {
            y = event.pageY;
            x = event.pageX;
            element.css({
                top: y + 'px',
                left: x + 'px'
            });
        }

        function mouseup(event) {
            $document.unbind('mousemove', mousemove);
            $document.unbind('mouseup', mouseup);
            console.log('mouseup', startX, startY, event.screenX, event.screenY);
            var mid = windowWidth / 2;

            if (sourceX < mid && event.pageX >= mid) {
                // yes there was a change of sides
                scope.bill.markCooking(); // change the status to COOKING
                console.log('moved to COOKING', scope.bill.getStatus());
            } else if (sourceX >= mid && event.pageX < mid) {
                scope.bill.enq(); // change the status to NEW
                console.log('moved to ENQ', scope.bill.getStatus());
            }
        }
    }
}})

我在这里做错了什么?

【问题讨论】:

  • 您需要更新scope.apply中的角度变量
  • 完美,谢谢@Anand

标签: javascript angularjs angularjs-directive


【解决方案1】:

只要你在浏览器事件处理程序中,你实际上就在 Angular 的生命周期之外。用户的操作触发了事件,但 Angular 不知道它需要检查和更新其绑定(在本例中为账单状态)。

手动调用 scope.$apply() 会触发 Angular 的变更检测,并会更新您的绑定:

scope.$apply(function() {
  if (sourceX < mid && event.pageX >= mid) {
    // yes there was a change of sides
    scope.bill.markCooking(); // change the status to COOKING
    console.log('moved to COOKING', scope.bill.getStatus());
  } else if (sourceX >= mid && event.pageX < mid) {
    scope.bill.enq(); // change the status to NEW
    console.log('moved to ENQ', scope.bill.getStatus());
  }
});

您可以在此处阅读有关范围及其​​生命周期的更多信息:http://docs.angularjs.org/guide/scope

【讨论】:

  • 只要你在浏览器事件处理程序中,你实际上就在 Angular 的生命周期之外。仅当您不使用 Angular 支持的 ng-* 事件时才会这样。
  • 如果有疑问,并且您没有看到更新的视图,您可以随时尝试调用 apply() 以查看它是否解决了问题。如果您已经处于摘要周期中,Angular 会对您大喊大叫,因此您会知道这是否是问题所在。听起来好像就在这里。
  • 像魅力一样工作,感谢您的资源!添加作为答案。
  • @thescientist 绝对,我应该更清楚。不使用 Angular 指令的手动绑定事件将需要 $apply() 来更新范围。
  • @Ashesh 取决于您如何创建指令。一个元素只能有一个隔离范围。也许看看这个答案:stackoverflow.com/questions/20609770/…
猜你喜欢
  • 2013-09-23
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-13
  • 2016-02-27
  • 2014-10-07
相关资源
最近更新 更多