I have a walkthrough in my app which prises 4 pages. I decided to make the Walkthrough a single state with multiple views to represent each of the 4 pages.
In my html I define a div as a ui-view pointed to the current view, which my controller then changes around as necessary.
The problem is, when I update $scope.currentView to 'general' it does not change what's actually seen on the screen! If I manually change it to 'general' in my _init function it does show the general page, but I cannot make it change based on a button click.
HTML:
<div ui-view="{{currentView}}@walkthrough"></div>
Controller:
var _init = function () {
$scope.currentView = 'wele';
};
_init();
$scope.setView = function (view) {
$scope.currentView = view;
};
My state definition:
.state('walkthrough', {
url: '/walkthrough',
views: {
'': {
templateUrl: 'app/walkthrough/walkthrough.html',
controller: 'walkthroughController'
},
'wele@walkthrough': {
templateUrl: 'app/walkthrough/wele.html'
},
'general@walkthrough': {
template: 'general'
}
}
})
And the button to update the view:
<img class="start-button center-block" ng-click="setView('general')" />
Update 1
I have tried the following to solve, none of which worked:
- Changing currentView to a getter function getCurrentView() which returns the currentView. Same behavior.
- Wrapping the currentView setter in a $scope.$apply. Get the $apply already in progress error
- Wrapping the currentView setter in a $timeout. Same behavior
Update 2
I added a <pre>
section which calls the identical code as in the ui-view, {{currentView}}@walkthrough
. It shows the correct view, even though the page itself doesn't update the show the new view.
Update 3
I have tried every bination of how to programmatically set the view but nothing I've tried has worked. Whether I use a server to grab the view, function, straight up $scope variable, nothing. The variable itself is correct, but the view just won't change when I change the variable.
The strange part is it works once when I set the value of the currentView in my init() function. It works if I change the value to one of the next views in the code itself ($scope.currentView = 'general' <- this shows the general page), but not if I make a button click change the currentView to 'general'.
I've tried all manner of $scope.$applys, $digests, and $timeouts. Nothing I do will get the view itself to update. The only thing left is to make it into a bunch of divs with ng-show/hide which is really ugly and a pain to manage, and the reason I wanted to use views in the first place.
Update 4
Still no progress, regardless of what I try... I thought some weird bination of wrapping the variable change in a $timeout might prove useful but alas, nothing. My last thought was to change all of these to their own independent states, but then I'll end up with a bunch of duplicated code which is obviously not good. I use almost the same type of change in other section of my app (to change states though, not views), and it works perfectly. I cannot figure out why I can't change the view dynamically. Any help would be greatly appreciated.
Update 5
Had some home after user's ment below but it has lead nowhere. I have tried to call all manner of $state changes to refresh the view but nothing has worked. I tried all of the follow, none of which had any impact on the page:
$state.reload();
$state.go($state.current, {}, { reload: true });
$state.transitionTo($state.current, $stateParams, {
reload: true,
inherit: false,
notify: true
});
I have a walkthrough in my app which prises 4 pages. I decided to make the Walkthrough a single state with multiple views to represent each of the 4 pages.
In my html I define a div as a ui-view pointed to the current view, which my controller then changes around as necessary.
The problem is, when I update $scope.currentView to 'general' it does not change what's actually seen on the screen! If I manually change it to 'general' in my _init function it does show the general page, but I cannot make it change based on a button click.
HTML:
<div ui-view="{{currentView}}@walkthrough"></div>
Controller:
var _init = function () {
$scope.currentView = 'wele';
};
_init();
$scope.setView = function (view) {
$scope.currentView = view;
};
My state definition:
.state('walkthrough', {
url: '/walkthrough',
views: {
'': {
templateUrl: 'app/walkthrough/walkthrough.html',
controller: 'walkthroughController'
},
'wele@walkthrough': {
templateUrl: 'app/walkthrough/wele.html'
},
'general@walkthrough': {
template: 'general'
}
}
})
And the button to update the view:
<img class="start-button center-block" ng-click="setView('general')" />
Update 1
I have tried the following to solve, none of which worked:
- Changing currentView to a getter function getCurrentView() which returns the currentView. Same behavior.
- Wrapping the currentView setter in a $scope.$apply. Get the $apply already in progress error
- Wrapping the currentView setter in a $timeout. Same behavior
Update 2
I added a <pre>
section which calls the identical code as in the ui-view, {{currentView}}@walkthrough
. It shows the correct view, even though the page itself doesn't update the show the new view.
Update 3
I have tried every bination of how to programmatically set the view but nothing I've tried has worked. Whether I use a server to grab the view, function, straight up $scope variable, nothing. The variable itself is correct, but the view just won't change when I change the variable.
The strange part is it works once when I set the value of the currentView in my init() function. It works if I change the value to one of the next views in the code itself ($scope.currentView = 'general' <- this shows the general page), but not if I make a button click change the currentView to 'general'.
I've tried all manner of $scope.$applys, $digests, and $timeouts. Nothing I do will get the view itself to update. The only thing left is to make it into a bunch of divs with ng-show/hide which is really ugly and a pain to manage, and the reason I wanted to use views in the first place.
Update 4
Still no progress, regardless of what I try... I thought some weird bination of wrapping the variable change in a $timeout might prove useful but alas, nothing. My last thought was to change all of these to their own independent states, but then I'll end up with a bunch of duplicated code which is obviously not good. I use almost the same type of change in other section of my app (to change states though, not views), and it works perfectly. I cannot figure out why I can't change the view dynamically. Any help would be greatly appreciated.
Update 5
Had some home after user's ment below but it has lead nowhere. I have tried to call all manner of $state changes to refresh the view but nothing has worked. I tried all of the follow, none of which had any impact on the page:
$state.reload();
$state.go($state.current, {}, { reload: true });
$state.transitionTo($state.current, $stateParams, {
reload: true,
inherit: false,
notify: true
});
Share
Improve this question
edited Mar 2, 2015 at 10:07
Joshua Ohana
asked Mar 1, 2015 at 17:29
Joshua OhanaJoshua Ohana
6,14115 gold badges64 silver badges121 bronze badges
3
-
Can you post the code for how the view ID is being passed to
setView
on click? – Aweary Commented Mar 1, 2015 at 17:31 - @Aweary <img class="start-button center-block" ng-click="setView('general')" /> – Joshua Ohana Commented Mar 1, 2015 at 17:32
- @Aweary I trued using ng-click="currentView='general'" but that doesn't change the view at all (even when looking at debug vals) – Joshua Ohana Commented Mar 1, 2015 at 17:41
2 Answers
Reset to default 3While the ui-view directive will take an interpolated value ({{ something }}
) for the view name, it doesn't actually watch this for changes. Instead, view updates are only triggered by the $stateChangeSuccess
and $viewContentLoading
events. This is why you can observe it working the first time and only the first time.
You can verify this by looking at the linking function for the $ViewDirective
in ui-router's source code: https://github./angular-ui/ui-router/blob/master/src/viewDirective.js.
This means that your setView
function needs to call $state.go
to trigger a state change, rather than just setting a property on scope. As pe the usual state change process, this will eventually result in a $stateChangeSuccess
event being broadcast.
So I solved this by just making every walkthrough page its own inherited state from parent walkthrough, each with the single view. Probably not the best method but I don't want to waste more time on this.
I would still love a method to just use nested views and navigate that way, since it'll be easier to add more in the future with that method without bloating my stateProvider.
.state('walkthrough', {
url: '/walkthrough',
views: {
'': {
templateUrl: 'app/walkthrough/walkthrough.html',
controller: 'walkthroughController'
}
}
})
.state('walkthrough.wele', {
url: '/wele',
views: {
'walkthrough.wele@walkthrough': {
templateUrl: 'app/walkthrough/wele.html'
}
}
})
.state('walkthrough.general', {
url: '/general',
views: {
'walkthrough.general@walkthrough': {
templateUrl: 'app/walkthrough/general.html'
}
}
})
.state('walkthrough.business', {
url: '/business',
views: {
'walkthrough.business@walkthrough': {
templateUrl: 'app/walkthrough/business.html'
}
}
})
.state('walkthrough.friends', {
url: '/friends',
views: {
'walkthrough.friends@walkthrough': {
templateUrl: 'app/walkthrough/friends.html'
}
}
})
Now I can easily navigate between by using
<img ui-sref="walkthrough.general" />
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744210345a4563302.html
评论列表(0条)