angular ui-router中的Named视图没有更新,尽管它被监视了

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

本文关键字:监视 更新 中的 ui-router Named 视图 angular      更新时间:2023-09-26

我有一个范围变量$scope.foo,我一直在监视。它可以通过表单中的文本字段进行更新。

我有两个命名视图AB在我使用角ui-router渲染的页面上。命名视图A具有文本表单字段,通过ng-model="foo"监视控制器中的更改。当foo的值被用户改变时,它会改变控制器中另一个作用域变量$scope.bar的值,这是一个数组,在命名视图B上的ng-repeat指令中使用。$scope.bar中的更改是使用控制器中的$scope.$watch方法进行的。

我面临的问题是,当foo被改变时,我可以看到bar在命名视图A上的变化,但不是在命名视图B上。

有人能帮我解决这个问题吗?

编辑:

有一个柱塞,这应该表明您的场景正在工作。

解决方案中最重要的部分是由:

  • 仅通过视图层次继承(引用:)

请记住,只有当状态的视图嵌套时,作用域属性才会向下继承状态链。作用域属性的继承与状态的嵌套无关,而与视图(模板)的嵌套有关。

这是完全可能的,你有嵌套的状态,其模板填充ui-视图在各种非嵌套的位置在你的网站。在这种情况下,你不能期望在子状态视图中访问父状态视图的作用域变量。

让我再表达一次: 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)set from bar 2) $watch和3)set back to bar来跟随问题描述…但是如果数组包含对象,我们可以直接处理它们……没有这些开销,但那是另一个故事…

检查这里是如何工作的,并且视图A中的任何更改也在B中可见…因为继承了数组 bar 在parent $scope中声明的引用。

我创建了第二个答案,也遵循这个柱塞中的问题,@skip (OP)通过我作为问题的例子。

首先有一个更新的工作版本

的活塞,这是我们需要的。以下是主要的变化:

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]);
    }
  }
});

但是现在我们有两个(Parent和child):

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]);
    }
  }
});

需要提及的重要部分

。最小公分母

我们必须将共享集合(数组栏)移动到父元素中。为什么?

我们必须将共享引用移动到最小公分母——父作用域

  • 如何防止重新加载命名视图,当状态改变?AngularJS UI-Router

二世。对数组的引用必须保持不变

我们必须保持对$scope.bar的引用不变!这是必不可少的。如何做到这一点?看到:

  • 替换数组内容的简写方法

不创建新的引用,而是清除数组,保留对它的引用

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

III。控制器可以有多个实例

此外,两个视图AB具有相同的控制器(实际上相同的控制器名称)这一事实绝对不意味着它们是相同的实例。

,它们是两个不同的实例…不分享任何东西。我想这是最关键的困惑。看到

  • angularjs指南-依赖注入

控制器是特殊的,与服务不同,在应用程序中可以有许多控制器的实例。例如,模板中每个ng-controller指令都有一个实例。

请注意,所有在更新后的示例