簡體   English   中英

盡管被觀看,角度ui-router中的命名視圖仍未更新

[英]Named view in angular ui-router not updating, despite being watched

我有一個范圍變量$scope.foo ,我正在監視。 它可以通過表單中的文本字段進行更新。

我在使用angular ui-router渲染的頁面上有兩個命名視圖AB 命名視圖A具有文本表單字段,通過ng-model="foo"監視控制器中的更改。 當用戶更改foo的值時,它會在命名視圖B上的ng-repeat指令中使用的控制器中更改另一個作用域變量$scope.bar (這是一個數組)的值。 $scope.bar的更改是使用控制器中的$scope.$watch方法進行的。

那我現在面臨的問題是,當foo改變,我可以看到的變化bar上的命名視圖A不能命名視圖上B

有人可以幫我解決這個問題嗎?

編輯是此問題的plunker。

有一個plunker ,它應該表明您的方案正在運行。

該解決方案最重要的部分是:

請記住, 只有嵌套狀態的視圖時, 范圍屬性才會繼承狀態鏈 范圍屬性的繼承與狀態的嵌套以及與視圖(模板)的嵌套有關的所有內容都無關。

完全有可能您有嵌套狀態,其模板在您站點內的各種非嵌套位置填充ui-views。 在這種情況下,您不能指望在子狀態視圖中訪問父狀態視圖的范圍變量。

讓我再次表達一下: scope繼承只能通過view嵌套來實現

有了它,我們可以創建這種狀態定義:

$stateProvider
    .state('root', { 
        url: '/root',
        templateUrl: 'tpl.root.html',
        controller: 'RootCtrl',            // this root scope will be parent
    })
    .state('root.entity', {
        url: '/entity',
        views:{
            'A': {
                templateUrl: 'tpl.a.html',
                controller: 'ACtrl',        // scope is inherited from Root
            },
            'B': {
                templateUrl: 'tpl.b.html',
                controller: 'ACtrl',        // scope is inherited from Root
            }
        }
    })

所以狀態定義支持嵌套視圖 - 讓我們從中獲利並將$scope.bar集合放入父級。 然后,所有涉及的視圖都可以訪問相同的集合:

.controller('RootCtrl', function ($scope, $state) {
  $scope.bar = ['first', 'second', 'last'];

})
.controller('ACtrl', function ($scope, $state) {
  // *) note below
  $scope.foo = $scope.bar[0];
  $scope.$watch("foo", function(val){$scope.bar[0] = val; });
})
.controller('BCtrl', function ($scope, $state) {

})

*)注意:這里我們做1)設置從2)$ watch和3)設置回bar以跟隨問題描述...但是如果數組包含對象,我們可以直接使用它們...沒有它開銷,但這是另一個故事......

檢查這是如何工作的,並且視圖A中的任何更改在B ...中也是可見的,因為繼承了對父$ scope中聲明的數組bar引用。

我創建了第二個答案,也跟着問題在這個plunker ,這@skip(OP)傳給我的FO問題的例子。

首先是更新的工作版本

那個plunker ,它做我們需要的。 主要變化有:

原始state def:

.state('home', {
            url: '/',
            views: {

                '': { templateUrl: 'home.html' },

                'A@home': {
                    templateUrl: 'a.html',
                    controller: 'MainCtrl'
                },

                'B@home': {
                    templateUrl: 'b.html',
                    controller: 'MainCtrl'
                }
            }

RootCtrl定義取代:

.state('home', {
            url: '/',
            views: {

                '': { 
                  templateUrl: 'home.html', 
                  controller: 'RootCtrl' // here we do use parent scoping
                },

                'A@home': {
                    templateUrl: 'a.html',
                    controller: 'MainCtrl'
                },

                'B@home': {
                    templateUrl: 'b.html',
                    controller: 'MainCtrl'
                }
            }

這是一個控制器:

app.controller('MainCtrl', function($scope) {
  var fruits = [{"name": "Apple"}, {"name": "Banana"}, {"name": "Carrot"}];

  $scope.bar =  $scope.bar || []; 

  $scope.foo = 2;

  $scope.$watch('foo',function(value, oldValue){
      $scope.bar = [];
      getBar(fruits, value);
  });

  function getBar(fruits, howManyFruits) {
    for(var i=0; i < $scope.foo; i++) {
        $scope.bar.push(fruits[i]);
    }
  }

});

但現在我們有兩個(父母和孩子):

app.controller('RootCtrl', function($scope) { 
  $scope.bar = []; 
})
app.controller('MainCtrl', function($scope) {
  var fruits = [{"name": "Apple"}, {"name": "Banana"}, {"name": "Carrot"}];

  //$scope.bar =  $scope.bar || []; 

  $scope.foo = 2;

  $scope.$watch('foo',function(value, oldValue){
      $scope.bar.length = 0;
      getBar(fruits, value);
  });

  function getBar(fruits, howManyFruits) {
    for(var i=0; i < $scope.foo; i++) {
        $scope.bar.push(fruits[i]);
    }
  }

});

一些重要的部分要提

I.最不常見的分母

我們必須將共享集合(數組欄)​​移動到父集合中。 為什么?

我們必須將共享引用移動到最小公分母 - 到父范圍

看到

II。 數組引用必須保持不變

我們必須保持對Parent $scope.bar的引用不變 這很重要。 怎么實現呢? 看到:

而不是創建新的引用,我們清除數組,保持對它的引用

// wrong
$scope.bar = [];
// good
$scope.bar.length = 0;

III。 控制器可以有多個實例

此外,視圖AB都具有相同的控制器(實際上是相同的控制器名稱)的事實 ,絕對不是說它們是相同的實例。

,他們是兩個不同的實例......不分享任何東西。 這是我猜,最關鍵的混亂。 看到

控制器的特殊之處在於,與服務不同,應用程序中可能存在許多實例 例如,模板中的每個ng-controller指令都會有一個實例。

請在更新的示例中觀察所有內容

暫無
暫無

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

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