angularjs - Angular Digest cycle being ran but ng-bind value not updating -
i have parent view contains navbar, , inside of view have <div ui-view>
element renders whatever child view i'm on.
i want conditionally show/hide navbar within parent view, based on route of child view. right now, have this:
<nav ng-show="!vm.hidenavbar">
the first time app loaded, vm.hidenavbar
set true , works expected.
after vm.hidenavbar
changed false, bound value not updated. still true
.
every controller in app extends basecontroller
:
export class basecontroller { public hidenavbar: boolean; constructor(public $scope: ibasescope, private $state: ng.ui.istateservice) { if ($state.current.url === '/login') { this.hidenavbar = true; } else { this.hidenavbar = false; } $scope.vm = this; } }
so, everytime new controller loaded, calls constructor basecontroller
, conditionally sets $scope.vm.hidenavbar
. if run $scope.$apply()
@ end of constructor, angular throws errors saying digest cycle being ran.
so, digest cycle being ran, value in view not being updated. thought have instantiated more 1 copy of basecontroller
since initial controller , controller navigated both extend controller. so, now, bound value of vm.hidenavbar
still looking @ old controller.
am on right track this? how can solve issue?
in case, suggest go view inheritance
(not controller
, not state
). check more details here:
there a working example
what need 'root'
state. super parent of other state
(states family). state definition:
$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, })
even other state hierarchy start 'root'
state:
$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 })
we can see many controllers:...
being defined, , here are:
module mynamespace { // real super parent of states // view inheritance (its $scope) // not 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 { } }
as mentioned in snippet comment - there inheritance, on code level. passed $scope
inherited view hierarchy.
the first controller in view hierarchy rootctrl
in fact only, assign (create) shared reference model rootsetting : {}
and derive 1 controller base:
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) { // in fact assigned in rootctrl // others (children) 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; } } } }
having in place, root template:
<div> <div ng-if="!rootsetting.hidenavbar"> ... // navbar </div> <div ui-view=""> // standard content of child views </div> </div>
we can see, here evaluate shared reference model rootsetting
, property hidenavbar
this real advantages of view inheritance
coming ui-router
.
check in action here
Comments
Post a Comment