Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 正在运行角度摘要循环,但ng绑定值未更新_Angularjs_Typescript_State_Angular Ui Router - Fatal编程技术网

Angularjs 正在运行角度摘要循环,但ng绑定值未更新

Angularjs 正在运行角度摘要循环,但ng绑定值未更新,angularjs,typescript,state,angular-ui-router,Angularjs,Typescript,State,Angular Ui Router,我有一个包含导航栏的父视图,在该视图中我有一个元素,它呈现我所在的任何子视图 我希望根据子视图的路径,在父视图中有条件地显示/隐藏导航栏。现在,我有这个: <nav ng-show="!vm.hideNavbar"> 因此,每次加载新控制器时,它都会调用BaseController的构造函数,并有条件地设置$scope.vm.hideNavbar。如果我在这个构造函数的末尾立即运行$scope.$apply(),angular会抛出错误,表示已经在运行摘要循环 因此,正在运行摘要循

我有一个包含导航栏的父视图,在该视图中我有一个
元素,它呈现我所在的任何子视图

我希望根据子视图的路径,在父视图中有条件地显示/隐藏导航栏。现在,我有这个:

<nav ng-show="!vm.hideNavbar">
因此,每次加载新控制器时,它都会调用
BaseController
的构造函数,并有条件地设置
$scope.vm.hideNavbar
。如果我在这个构造函数的末尾立即运行
$scope.$apply()
,angular会抛出错误,表示已经在运行摘要循环

因此,正在运行摘要循环,但我的视图中的值没有更新。我唯一的想法是,自从我的初始控制器和我导航到的控制器都扩展了这个控制器以来,我已经实例化了
BaseController
的多个副本。因此,现在,
vm.hideNavbar
的绑定值仍在查看旧控制器


我做得对吗?我如何解决这个问题?

在这种情况下,我建议使用
查看继承
(不是
控制器
,不是
状态
)。请在此处查看更多详细信息:

有 我们需要的是一个
“根”
状态。它将是任何其他州(州系列)的超级父级。这可能是国家的定义:

$stateProvider
  .state('root', {
      abstract: true,
      templateUrl: 'layout.tpl.html',
      controller: MyNamespace.RootCtrl,
  })

  .state('login', {
      parent: "root",
      url: "/login",
      templateUrl: 'tpl.html',
      controller: MyNamespace.LoginCtrl,
  })
  .state('home', {
      parent: "root",
      url: "/home",
      templateUrl: 'tpl.html',
      controller: MyNamespace.HomeCtrl,
  })
甚至其他一些状态层次结构也将以该
'root'
状态开始:

$stateProvider
  .state('parent', {
      parent: "root",
      url: "/parent",
      templateUrl: 'tpl.html',
      controller: MyNamespace.ParentCtrl
  })
  .state('parent.child1', { 
      url: "/child1",
      templateUrl: 'tpl.html',
      controller: MyNamespace.Child1Ctrl
  })
  .state('parent.child2', { 
      url: "/child2",
      templateUrl: 'tpl.html',
      controller: MyNamespace.Child2Ctrl
  })
我们可以看到许多
控制器:…
正在定义,它们是:

module MyNamespace {
    // the real SUPER parent of all states
    // but it is about VIEW inheritance (its $scope)
    // not about controller hierarchy
    export class RootCtrl extends BaseController {
    }

    export class HomeCtrl extends BaseController {
    }
    export class LoginCtrl extends BaseController {
    }
    export class ParentCtrl extends BaseController {
    }
    export class Child1Ctrl extends BaseController {
    }
    export class Child2Ctrl extends BaseController {
    }
}
正如在代码段注释中提到的,有继承,但只是在代码级别上。传递的
$scope
由视图层次结构继承

视图层次结构中的第一个控制器是
RootCtrl
,它实际上是唯一分配(创建)共享参考模型的控制器
rootSetting:{}

它们都来自于一个控制器基础:

module MyNamespace {
    export interface IRootSetting {
        hideNavbar: boolean;
    }
    export interface IMyRootScope extends ng.IScope {
        rootSetting: IRootSetting
    } 
    export interface IBaseScope extends IMyRootScope {

    }
    export class BaseController {
        public hideNavbar: boolean;
        static $inject = ['$scope', '$state'];

        constructor(public $scope: IBaseScope, 
                 protected $state: ng.ui.IStateService) {

                  // will be in fact assigned in the RootCtrl only
                  // all others (children) will get that reference
                  // via scope inheritance
                  $scope.rootSetting = $scope.rootSetting || {hideNavbar: false}; 

            if ($state.current.url === '/login') {
                this.$scope.rootSetting.hideNavbar = true;
            } else {
                this.$scope.rootSetting.hideNavbar = false;
            }
        }
    }
}
使用此根模板,将其放置到位:

<div>      
  <div ng-if="!rootSetting.hideNavbar"> 
   ... // navbar
  </div>      

  <div ui-view="">
      // standard content of child views
  </div>      
</div>

... // 导航栏
//子视图的标准内容
我们可以看到,这里我们评估了共享引用模型
rootSetting
及其属性
hideNavbar

这就是
用户界面路由器
提供的
视图继承的真正优势


在操作中检查它

这是为每个控制器使用
vm
的一个陷阱。子控制器正在设置自己的
hideNavbar
属性,这与设置父控制器的
hideNavbar
属性不同。除非您可以为每个控制器创建唯一的名称,否则您可能最终需要使用
$broadcast
$emit
来解决此问题。将布尔值设置为嵌套对象,如
this.navbar.status=false
<div>      
  <div ng-if="!rootSetting.hideNavbar"> 
   ... // navbar
  </div>      

  <div ui-view="">
      // standard content of child views
  </div>      
</div>