簡體   English   中英

如何通過服務強制在angularjs中查看更新?

[英]How to force view updates in angularjs by services?

我試圖持有一個提供導航菜單的全局MainCtrl控制器。 這些菜單項應不時由各種控制器進行更新。

現在,我想我可以將導航鏈接綁定到控制器,並按如下所示更新控制器變量:

<div ng-controller="MainCtrl">
    <li ng-repeat="nav in navigations">
        <a href="#{{nav.path}}">{{nav.label}}</a>
    </li>
</div>
<div ng-view></div> <!-- renders different controllers, eg testController.js -->

app.controller('MainCtrl', ['$scope', 'navigationService', function($scope, navigationService) {
    //binding the property of the service
    $scope.navigations = navigationService.navigations;
}]);

app.service('navigationService', function() {
    return {
        navigations: null
    };
});

但是,當調用服務並更新內部的navigations變量時,視圖中沒有任何更改。 為什么?

angular.module('test').controller('testController', ['$scope', '$http', 'navigationService', function($scope, $http, navigationService) {
    $http.get(url)
        .success(function(data) {
            navigationService.navigations = data.some.navigations; //assume json data exists
        });
}]);

如何實現這種雙向數據綁定,迫使視圖從一個控制器更新到另一個?

您正在從服務中返回primitive 基本體沒有繼承。

而是返回一個對象:

app.service('navigationService', function() {    
    var nav ={}; // object that will be returned       
    function init(){
        $http.get(url)
            .success(function(data) {
                // modify object returned from service rather than reassign a primitive value
                nav.items = data.some.navigations; exists
            });
    }

    init();//make request to load the data

    return { // can add more properties if needed           
        nav: nav
    };
});

然后在控制器中:

 $scope.navigations = navigationService.nav;
 // will initially be {} and later will inherit items property

視野中

<div ng-repeat="item in navigations.items">

有角度的內部手表將拾取現在對對象所做的更改並相應地渲染視圖

使用Angular超過2年后,我發現,每當您想要具有來自不同服務/控制器/指令的多重綁定的功能時,總會使用json屬性,並且永遠不要使用ovverride變量實例:

我將替換為:

$scope.navigations = navigationService.navigations;

接着就,隨即:

var state = {
   navigations: []
};
$scope.state = state;

state.navigations = navigationService.navigations;  // i prefer such syntax
// or
$scope.state.navigations = navigationService.navigations;

為什么? 可能是由於Angular自動將$ watch()/ $ watchCollection()函數綁定到變量更改。

您需要使用$ rootscope進行廣播,並注意廣播

假設您的數據已從x控制器更改,因此您可以在此處像這樣廣播

$rootScope.$broadcast('menu-need-to-refresh');

在您的主控制器中,像這樣

$scope.$on('menu-need-to-refresh', function (event, data) {
    $scope.menus= service.newMenu();
});

希望對您有幫助

更新 :@charlietfl + @Dmitri Algazin方法更優雅,因為它通過使用引用來利用javascript本身,並避免在控制器+ ngRepeat中使用兩個觀察程序(此指令中的watchCollection將完成工作)。

我的原始答案:

您應該使用$scope.$watchMainCtrl監視服務中的更改:

app.controller('MainCtrl', ['$scope', 'navigationService', function($scope, navigationService) {
    //binding the property of the service
    $scope.$watch(
        function(){
            return navigationService.navigations;
        }
    , function(newValue, oldValue){
        if(newValue !== oldValue){
            $scope.navigations = newValue;
        }
    })

}]);

我只是通過使用$ scope。$ watch解決了類似的問題

例如: $scope.$watch( function(){return navigationService.navigations;}, function(newVal, oldVal){$scope.navigations = newVal;} )此代碼未經測試,但您可以$scope.$watch( function(){return navigationService.navigations;}, function(newVal, oldVal){$scope.navigations = newVal;} )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM