AngularJS正在观看表情

时间:2015-06-20 09:49:32

标签: angularjs

说我们有这个表达

$scope.showButton = users.is_admin() && !document.is_provided;

然后在同一个控制器中,您有一个更新Document.is_provided的值的按钮:

<button ng-click="document.is_provided = true;">Provide document</button>

问题在于$scope.showButton现在应该改变,但它没有改变。

更新: Plnkr显示简化问题:http://plnkr.co/edit/Qk2jnHAmqsrNXSAjDYEk?p=preview

4 个答案:

答案 0 :(得分:4)

我想补充一下squiroid的答案并向你解释它为何有效。我将为您提供一种非常简单的理解方式,因为这对我来说也是一个非常常见的问题。

Angular有一个叫做Digest循环的东西。它是一系列连续调用的函数,以确保如果变量A与另一个变量B双向绑定(例如使用ng-model),它们始终保持同步(即,始终具有相同的值) )。 angular提供的函数(或通常以$开头的服务,如$ timeout等)自动启动摘要周期

所以让我们假设你有一个变量A并且你将它绑定到$ scope变量B,它等于变量C.你会期望C也被绑定到A,对吧?因为你认为当你改变C时,B应该改变,所以A也应该改变。但这只有在您开始摘要周期时才有可能。该循环将查找需要更新的变量,并将更新它们。但是,只需更改C的值,就不会触发摘要周期,因此您的更改永远不会传播到A.

当你在$ watch中添加一个变量时你做的是(如$建议的那样),你强行启动一个摘要周期。所以现在当你改变C时,你开始循环,它追踪它也需要更新A,这就是它的工作原理。

在您的示例中,$ scope.showButton绑定到document.is_provided。现在,您正在使用非角度函数来更改document.is_provided的值。这意味着您不会触发摘要周期,这意味着您的更改永远不会传播到$ scope.showButton。因此,showButton始终保持错误。

当然,还有一个例子可以帮助您理解: http://jsbin.com/vojoso/edit?js,console,output

观看控制台。我添加了日志以帮助您理解。 注释掉$ watch语句,看看会发生什么。 尝试理解它然后自己做,你会得到它。

希望我帮助过:)

答案 1 :(得分:3)

我不确定,但你可以看一下: -

$scope.$watch(function(){
    return Users.is_admin() && !Document.is_provided;
},fuction(newVal){
$scope.showButton =newVal;
});

希望有所帮助:)

答案 2 :(得分:2)

以下是关于$scope.$watch的好文章,它应该有助于了解如何解决您的问题。

你需要更大的答案添加代码来解释Document变量和你的REST服务。

UPD:我看到你改变了原来的问题。我想你的控制器有问题。请尝试隐式使用$scope,将data属性视为悲伤angular code style

同时显示模板中连接控制器的部分。

UPD 2:你对我的话有些误解,所以我修改了你的plunker example

<强>的index.html

<html ng-app="plunker">
  <body ng-controller="MainController as main">

    <div ng-show="main.data.document.is_provided">visible</div>
    <button ng-click="main.hide()">Hide</button>

    <script data-require="angular.js@1.4.x" 
            src="https://code.angularjs.org/1.4.1/angular.js" 
            data-semver="1.4.1"></script>
    <script src="app.js"></script>
  </body>
</html>

<强> app.js

angular
  .module('plunker', [])
  .controller('MainController', MainController);

function MainController() {
    var main = this;

    this.data = {
      document: {
        is_provided: true
      }
    };

    this.hide = hide;

    function hide() {
      main.data.document.is_provided = false;
    }
}

ng-click内部存在一个问题,因为应该有函数执行。您还使用ng-if代替ng-show

答案 3 :(得分:2)

处理此类问题的最佳方式(imho): 在您的视图中使用{{ anyObject | json }}

通过这种方式,您可以了解您正在使用的引用以及对象是否存在于您的范围中。使用| json会在您的对象存在但空白时为您提供荣誉{}。如果您的对象在您的范围内不可用注意,则打印&#39;。

在您的情况下,将body标签更改为:      <body ng-controller="MainCtrl as mainCtrl">

然后,在此控制器的html内添加:

DATA: {{mainCtrl | json}}

所以现在你看到你的变量了!而且你也看到点击按钮并没有改变布尔变量。

通过一些额外的调试和重写,这可行:

app.controller('MainCtrl', function($scope) {

var main = this;

this.data = {
  document: {
    is_provided: true
  }
};



$scope.hide = function() {
  console.log(main);
  main.data.document.is_provided = !main.data.document.is_provided;
}
});

和:     <button ng-click="hide()">Hide</button>(注意括号)