没有$ scope.$ watch的服务和控制器之间的双向绑定.这是不好的做法吗? [英] Two-way binding between service and controller without $scope.$watch. Is this a bad practice?

查看:53
本文介绍了没有$ scope.$ watch的服务和控制器之间的双向绑定.这是不好的做法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我听说,不应将服务链接到控制器中的作用域变量,因为视图可以直接访问服务.但是我想将我的作用域变量绑定到存储在服务中的数据,并且我希望该变量反映服务中的所有更改.我已经阅读了很多解决方法,并且如果我想从控制器中观察服务数据,则大多数人都被告知使用$ scope.$ watch.我已经写了一个简单的示例,而没有使用$ scope.$ watch,它的工作方式完全符合我的要求,但是我不确定,我可以使用类似的东西吗,或者这是一个不好的做法.我学习Ang大约2-3天,非常需要您的建议:

I've heard, that service should not be linked to scope variable in controller because view gains direct access to service. But i want to bind my scope variable to data that stored in service, and i want that variable to reflect all changes from service. I've read a lot of workaround, and in most of them were told to use $scope.$watch, if i want to watch service data from controller. I've wrote simple example without using of $scope.$watch, which is working exactly like i want, but i'm definitely not sure, can i use something like this, or it this a bad practice. I'm learning angular for about 2-3 days, and very need your advice:

html:

<div ng-controller="TestController">
    <p>Current value = {{ serviceData.getValue() }}</p>
    <input type="text" ng-model="newValue">
    <button ng-click="changeServiceData(newValue)">Change</button>
</div>

module.js

module.js

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

controller.js

controller.js

app.controller('TestController', function($scope, testService){
    $scope.serviceData = testService.getPublicData();
    $scope.changeServiceData = function(newValue){
        testService.setValue(newValue);
    }
});

service.js

service.js

app.factory('testService', function(){
    var value = null;
    return {
        setValue: function(newValue){
            value = newValue;
        },
        getPublicData: function(){
            return {
                getValue: function(){
                    return value;
                }
            }
        }
    }
});

总结,视图只能访问getter.为了更新数据,我正在使用服务,可以将其插入任何控制器中,并且服务中的所有更改都将反映在控制器和视图上.

Summarizing , view has access only to getters. To update data i'm using service, which i can inject in any controller, and all changes in service are reflected on controller, and on view.

更新: 我试图这样改变我的工厂:

UPDATE: I have tried to change my factory like this:

app.factory('testService', function(){
var value = null;
return {
    setValue: function(newValue){
        value = newValue;
    },
    getValue: function(){
        return value;
    }
}

});

并将getter分配给作用域:

and assign getter to scope:

app.controller('TestController', function($scope, testService){
    $scope.value = testService.getValue();
    $scope.changeServiceData = function(newValue){
        testService.setValue(newValue);
    }
});

在这种情况下,如果我使用setter从视图中更改服务中的值,则值在视图中不会隐式更改,它不会反映实际的服务数据.也许您可以解释这种行为?

In this case, if i changing value in service from view using setter, value doesnt changing implictly in view, it doesnt reflect actual service data. Maybe you could explain such behaviour?

推荐答案

您的更新几乎是正确的,如果您决定使用包含变量的服务,则意味着该模块将跨模块和控制器共享.

Your update is almost right, if you've decided to use a service containing a variable it is meant to be shared accross modules and controllers.

您需要做的只是立即使用此getter和setter:

What you need to do is only use this getter and setter now:

app.controller('TestController', function($scope, testService){
  $scope.testService = testService;
  $scope.newValue    = 'initial-value';
});

在您的HTML中:

<div ng-controller="TestController">
  <p>Current value = {{ testService.getValue() }}</p>
  <input type="text" ng-model="newValue">
  <button ng-click="testService.setValue(newValue)">Change</button>
</div>

现在,我们仍然将价值放在范围内,因为显然您只想在单击时更新服务值,因此需要与服务本身不同步.

Now we still put value into the scope because apparently you want to update the service value only on click, so it need to be desynchronized from the service itself.

如果要将服务值直接绑定到该输入的ngModel中,则不能使用getter,而必须直接使用变量:

If you want to bind the service value directly into the ngModel of that input, you cannot use a getter but will have to use the variable directly:

<input ng-model="testService.value">

最后一个选择是使用ngChange指令传播对newValue所做的任何更改:

Or one last option is to propagate any changes made to newValue using the ngChange directive:

<input ng-model="newValue" ng-change="testService.setValue(newValue)">

这篇关于没有$ scope.$ watch的服务和控制器之间的双向绑定.这是不好的做法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆