AngularJS:将服务变量绑定到控制器$ scope的值

时间:2021-09-28 20:25:14

I am creating a single-page AngularJS web app. My app needs to be able to query a backend service to get some information about a user's state, and this state information needs to be available to the various pieces of the single-page app. I created a service to manage this functionality, but I'm having trouble hooking things up in a way that seems reasonable to me.

我正在创建一个单页的AngularJS Web应用程序。我的应用程序需要能够查询后端服务以获取有关用户状态的一些信息,并且此状态信息需要可用于单页应用程序的各个部分。我创建了一个服务来管理这个功能,但是我很难以一种对我来说合理的方式挂钩。

Initially, I had things set up like this...

最初,我有这样的事情......

<service.js>
...
var url = 'www.my-backend.com';
this.val = [
    {
        name: 'undefined',
        isValid: false
    }
];
$http.get(url, {})
    .success (function (data) {
        this.val = data;
    })
    .error (function () {
        this.val =  [
            {
                name: 'error',
                isValid: false
            }
         ];
    });
...

And then in my controller...

然后在我的控制器中......

<controller.js>
...
$scope.val = service.val
...

This didn't work though (val.name was 'undefined'), presumably because service.val was bound to the controller's $scope before the get request had a chance to terminate. However, that does seem at odds with what I read here.

这不起作用(val.name是'undefined'),大概是因为service.val在get请求有机会终止之前绑定到控制器的$ scope。然而,这似乎与我在这里读到的内容不一致。

The next thing I did was this...

我接下来要做的就是......

<service.js>
...
var url = 'www.my-backend.com';
this.valPromise = $http.get(url, {});
...

And then in my controller...

然后在我的控制器中......

<controller.js>
...
$scope.val = [
    {
        name: 'undefined',
        isValid: false
    }
];
service.valPromise
    .success (function (data) {
        $scope.val = data;
    })
    .error (function () {
        $scope.val =  [
            {
                name: 'error',
                isValid: false
            }
         ];
    });
...

This worked, but I didn't like it. I feel like that logic belongs in the service.

这很有效,但我不喜欢它。我觉得这个逻辑属于服务。

So the next thing I did was work through the various suggestions that I found here, although none of them seemed to have the desired effect. I also saw this, but it seems like overkill and not really applicable to my problem.

所以我接下来要做的就是完成我在这里找到的各种建议,尽管它们似乎都没有达到预期的效果。我也看到了这一点,但它似乎有点矫枉过正,并不适用于我的问题。

Ideally I'd really like to figure out how to get my first attempt working (tightly bind my service variable to my controller scope by reference), but if that's not something that can really be done within the Angular framework, I'm happy to use some kind of watch behavior. Can anyone spot what I'm doing wrong or why my service variable isn't getting properly hooked up to my controller?

理想情况下,我真的想弄清楚如何让我的第一次尝试工作(通过引用将我的服务变量紧密绑定到我的控制器范围),但如果这不是可以在Angular框架内真正完成的事情,我很高兴使用某种手表行为。任何人都可以发现我做错了什么或为什么我的服务变量没有正确地连接到我的控制器?

2 个解决方案

#1


2  

In your $http callbacks this is not the service. You'll find plenty of answers about the meaning of this on SO. You need to refer to the service via a variable.

在你的$ http回调中,这不是服务。你会在SO上找到关于这个含义的大量答案。您需要通过变量引用服务。

The second problem is that this.val = data; would assign a new value to the service, but doesn't change the data in the scope, which still points to the old array. So you need to copy the new data to the existing array.

第二个问题是this.val = data;将为服务分配一个新值,但不会更改范围中的数据,这仍然指向旧数组。因此,您需要将新数据复制到现有阵列。

var service = this;
$http.get(url, {})
.success (function (data) {
    angular.copy(data, service.val);
})

#2


0  

I ran into this problem the other day. The reason it does not get set is because there is a race condition and because the data access is inside the service layer, it will lose every time. It seems like there should be a easy way to do this. I ended up just having my initial controller make the data access calls and set the properties in the service for other controllers to get.

前几天我遇到了这个问题。它没有设置的原因是因为存在竞争条件,并且因为数据访问在服务层内部,所以每次都会丢失。似乎应该有一个简单的方法来做到这一点。我最终只是让我的初始控制器进行数据访问调用,并在服务中设置属性以供其他控制器使用。

#1


2  

In your $http callbacks this is not the service. You'll find plenty of answers about the meaning of this on SO. You need to refer to the service via a variable.

在你的$ http回调中,这不是服务。你会在SO上找到关于这个含义的大量答案。您需要通过变量引用服务。

The second problem is that this.val = data; would assign a new value to the service, but doesn't change the data in the scope, which still points to the old array. So you need to copy the new data to the existing array.

第二个问题是this.val = data;将为服务分配一个新值,但不会更改范围中的数据,这仍然指向旧数组。因此,您需要将新数据复制到现有阵列。

var service = this;
$http.get(url, {})
.success (function (data) {
    angular.copy(data, service.val);
})

#2


0  

I ran into this problem the other day. The reason it does not get set is because there is a race condition and because the data access is inside the service layer, it will lose every time. It seems like there should be a easy way to do this. I ended up just having my initial controller make the data access calls and set the properties in the service for other controllers to get.

前几天我遇到了这个问题。它没有设置的原因是因为存在竞争条件,并且因为数据访问在服务层内部,所以每次都会丢失。似乎应该有一个简单的方法来做到这一点。我最终只是让我的初始控制器进行数据访问调用,并在服务中设置属性以供其他控制器使用。