2014-10-03 52 views
1

我在AngularJS的数据绑定中遇到了一些麻烦。 总之,我试图将我的工厂变量链接到我的视图($ scope)。 工厂(在我的完整实现中)侦听特定的广播并更新变量,视图应该反映这种变化,但事实并非如此。Angularjs在工厂和视图之间进行数据绑定

我设法从大部分其他代码中分离出这个问题。控制器调用的函数(setTrue)只是一些难度较大的后端操作的占位符。

运行代码时,我希望在视图中看到“true”。我不知道为什么这个观点仍然是“假”?

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script> 
<body ng-app="app"> 
    <div ng-controller="Fact"> 
     value: {{model}}<br/> 
    </div> 

    <script type="text/javascript"> 
     var app = angular.module("app", []); 

     app.controller('Fact', ['$scope','Fact', function ($scope, Fact) { 
      $scope.model = Fact.data; 
      Fact.setTrue(); 
     }]); 

     app.factory("Fact", function() { 
      var Fact = {}; 
      Fact.data = false; 

      Fact.setTrue = function() { 
       Fact.data = true; 
      }; 

      return Fact; 
     }); 
    </script> 
</body> 

Plunker:http://plnkr.co/edit/IIq2H4gW1DBoe5zVPx0g

可有人告诉我,我做错了什么?

编辑:

当我改变了上面的代码有

$scope.model = Fact; 

value: {{model.data}} 

这突然的作品...但我不喜欢把我的整个工厂都在我的范围内。

+2

布尔值通过值传递,而不是通过引用 – JoseM 2014-10-03 14:10:48

+1

为什么您反对将工厂对象放在范围内?这是做到这一点的正确方法,当你创建一个工厂它是一个单身对象,并且它应该被用来设置范围值 – 2014-10-03 14:40:16

+0

@JaredReeves如果我只是把工厂放在$ scope中,那么我真的不会看到有控制器的一点? – user3319803 2014-10-03 14:45:29

回答

0

调用正如你已经知道下面的代码将正常工作。正如你所看到的,我将返回的单例赋值给一个范围值。从这我可以瘦调用这个新的作用域对象的工厂返回的所有方法。

angular.module("app", []) 
 
    .controller('appCtrl', ['$scope', 'Fact', 
 
    function($scope, Fact) { 
 
     $scope.model = Fact; 
 
     $scope.model.setTrue(); 
 
    } 
 
    ]).factory("Fact", function() { 
 
    var Fact = {}; 
 
    Fact.data = false; 
 

 
    Fact.setTrue = function() { 
 
     Fact.data = true; 
 
    }; 
 

 
    return Fact; 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script> 
 

 
<div ng-app="app"> 
 
    <div ng-controller="appCtrl"> 
 
    value: {{model.data}} 
 
    <br/> 
 
    </div> 
 
</div>

在你的情况,我认为这将是完成你想要什么样的正确方法。我假设你可以考虑其他工厂可能有大量关联的场景,并且可以访问控制器中的整个对象。

在下面的代码片段中,我将布尔值封装在一个对象中,并像您一样分配给作用域,但现在任何更改都将绑定到$ scope.model对象。

angular.module("app", []) 
 
    .controller('appCtrl', ['$scope', 'Fact', 
 
    function($scope, Fact) { 
 
     $scope.model = Fact.data 
 
     Fact.setTrue(); 
 
     //$scope.model.setTrue(); 
 
    } 
 
    ]).factory("Fact", function() { 
 
    var Fact = {}; 
 
    Fact.data = {"value":false}; 
 

 
    Fact.setTrue = function() { 
 
     Fact.data.value = true; 
 
    }; 
 

 
    return Fact; 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script> 
 
<div ng-app="app"> 
 
    <div ng-controller="appCtrl"> 
 
    value: {{model.value}} 
 
    <br/> 
 
    </div> 
 
</div>

但是,如果你不想做这样的,只是想将数据值分配给范围,需要改变的事实工厂指派的值之前范围或将其包装在一个对象中,然后该对象将传递引用而不是值。应该注意的是,在你的代码中,你为$ scope.model指定了一个布尔值,但是它并没有绑定到Fact.data,因此对Fact的任何改变都不会影响模型对象。

+0

你的第二种方法就是我最终使用的方法。所以把它包裹在一个物体中。你认为某种方法比另一种更好吗? – user3319803 2014-10-03 15:35:32

+0

这真的取决于实施。我更喜欢第二种方法,因为它可以让你在工厂调用函数而不是新对象,如果你的数据是一个更复杂的对象(比如用户对象),那么你尤其如此,那么你将一些属性绑定到范围。 – 2014-10-03 15:39:37

+0

请注意,你会遇到其他情况,你需要将一个布尔值包装在一个对象中才能绑定到工作中,我可以想到的一种情况是ng-if。 – 2014-10-03 15:41:03

0

我对你使用工厂的方式感到非常惊讶。

你是不是应该做更多的东西一样:

(function() { 
angular.module("services") 
.factory("dataService", function ($http) { 

    var data = ""; 

    var getData = function() { 
    return data; 
    } 

    var setData = function(newData) { 
    data = newData; 
    } 

    return { 
    getData: getData, 
    setData: setData 
    }; 

}); 

})();

,然后你只需要在你的控制器

app.controller('Ctrl', ['$scope','dataService', function ($scope, dataService) { 
     $scope.model.data = dataService.getData(); 
     dataService.setData("something"); 
    }]); 
+0

你正在使用的符号也是可能的。我只是在学习一些教程,并在那里展示了这种写作方式。 但是(据我所知)你不应该在Angular中使用getters和setter,只需使用自动数据绑定。 – user3319803 2014-10-03 14:59:54

+0

@sam你确定这有效吗?因为'data = newData;'会破坏数据绑定,并且控制器的作用域不会更新。 我认为这只适用于'angular.extend(data,newData);' – ProblemsOfSumit 2015-11-17 16:26:27

相关问题