将服务的值绑定到控制器,以便在服务更新时更新

时间:2014-10-09 05:54:35

标签: angularjs

有很多参考文献都在讨论这个问题,但我只是需要有人来确认这是否正确。如果我有一个服务,我想与控制器共享信息,并且控制器应该更新服务的更改,我需要从服务返回一个对象,如:

.factory('myService', ['$http', function($http) {

    var data = {};

    var service = {
        constant: 1234,
        getData: function() {
            return data;
        },
        doCalculation: function() {
            service.constant = data.const*25;
        },
        requestData: function() {
            return $http.get('/blah')
                       .then(function( response ) {
                           data = response.data;
                       }
        }
    }

    return service;
}])

现在将它传递给控制器​​以供使用,并且如果在可能的路由resolve()期间再次调用requestData时更新它,我会做并且不能这样做:

.controller('myCtrl', ['myService', function(myService) {

    var self = this;

    // PART 1
    self.data = myService.constant;  // this is not bound and will not update, yes? 
    self.data1 = myService.getData(); // this is not bound and will not update, yes?
    // So, the above would be assigned or invoked only once on init of controller and 
    // would have to reset manually by assigning either a value or the result of the 
    // the function call again

    self.myService = myService; // pass entire service
    // Now, in controller functions or in the UI I can invoke the functions or access
    // values, and those results will be bound and update on changes to the service
    // since I've passed it in its entirety

    self.getData = function() {
        return self.myService.getData();
    }

    // PART 2
    self.getData = myService.getData; // would you ever do this?
    // You wouldn't have to pass the entire service if it had a bunch of different
    // parts that maybe you didn't want to be available...

}]);

PART 1
<div ng-show="myCtrl.myService.doCalculation() === someNumber">You can't see me unless doCalculation resolves to someNumber</div>

PART 2
<div ng-show="myCtrl.getData() === anotherNumber">Would this work? and would you want to do this?</div>

我似乎无法理解如何在服务和控制器之间共享数据,以及何时工作以及何时工作。如果你所能做的就是说出正确,错误,错误,那么这么错,那就是错误,但如果你也可以这么说,这就是为什么,我最欣慰的是把它当作最后的解决方案所以我不会继续质疑它。

1 个答案:

答案 0 :(得分:1)

我不会在这里走得太远......

controller是您观看的帮助。您需要在示波器上生成变量和函数,以帮助您的视图完成任务。

您的商业模式是您希望一个参考。

我所做的是在service上创建我的商业模式,因此多个实体可以共享(例如,其他服务,指令,控制器等)。

当我的controller开始时,我会从service添加指向模型的指针,并在它们之间使用相同的引用。我将模型属性绑定到视图。

所以:

  1. controller拥有自己的方法(不要共享service's方法)。 controllers方法应该简短,并使用service方法作为帮助。

  2. controller应该引用由service创建的商业模式。您的所有ajax来电均应来自该服务并填充\发送service所持有的模型。

  3. controller应具有基本视图函数(例如,决定将哪个css类应用于元素)。当您提交表单时,controller函数应该调用service's提交来执行ajax调用。

  4. 示例:

    HTML:

    <div ng-app="app">
        <div ng-controller="myCtrl">
            <input type="text" ng-model="Model.propA" />
            <br/>
            <input type="text" ng-model="Model.propB" />
            <div ng-show="ShouldShowSecondDiv()">Second Div.</div>
            <br/>
            <button ng-click="SubmitForm()">Submit</button>
        </div>
    </div>
    

    JS:

       var app = angular.module('app', []);
    
    app.controller('myCtrl', function ($scope, myService) {
        // simple controller "view method".
        $scope.ShouldShowSecondDiv = function () {
            return $scope.Model.propB > 12;
        };
    
        // "complex" "non-view method" -> use service.
        $scope.SubmitForm = function () {
            myService.SubmitModelToServer();
        };
    
        // get the ref. from the service.
        $scope.Model = myService.GetModel();
    });
    
    app.service('myService', function () {
        this.Model = {};
    
        // perform an ajax to get the model or whatever.
        this.GetModel = function () {
            this.Model = {
                propA: 'Im prop A',
                propB: 12
            };
    
            return this.Model;
        };
    
        // submit it to the server via $http. Check the log and you will see the binding(if you changed a value in the view).
        this.SubmitModelToServer = function () {
            console.log("ajax or whatever....submitted");
            console.log(this.Model);
        };
    });
    

    JSFIDDLE