在 AngularJS UI-Router 中动态改变视图 [英] Dynamically changing View in AngularJS UI-Router

查看:19
本文介绍了在 AngularJS UI-Router 中动态改变视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有一个包含 4 页的演练.我决定让演练成为具有多个视图的单一状态来代表 4 个页面中的每一个.

在我的 html 中,我将一个 div 定义为指向当前视图的 ui-view,然后我的控制器会根据需要对其进行更改.

问题是,当我将 $scope.currentView 更新为 'general' 时,它不会改变屏幕上实际看到的内容!如果我在 _init 函数中手动将其更改为常规",它会显示常规页面,但我无法根据单击按钮进行更改.

HTML:

<div ui-view="{{currentView}}@walkthrough"></div>

控制器:

var _init = function () {$scope.currentView = '欢迎';};_在里面();$scope.setView = 函数(视图){$scope.currentView = 视图;};

我的状态定义:

.state('演练', {网址:'/演练',意见:{'':{templateUrl: 'app/walkthrough/walkthrough.html',控制器:'walkthroughController'},欢迎@演练":{templateUrl: 'app/walkthrough/welcome.html'},'一般@演练':{模板:'一般'}}})

以及更新视图的按钮:

<小时>

更新 1

我尝试了以下解决方法,但没有一个奏效:

  1. 将 currentView 更改为返回 currentView 的 getter 函数 getCurrentView().相同的行为.
  2. 将 currentView setter 包装在 $scope.$apply 中.获取 $apply already in progress 错误
  3. 在 $timeout 中包装 currentView setter.相同的行为

更新 2

我添加了一个

 部分,它调用与 ui-view 中相同的代码,{{currentView}}@walkthrough.它显示了正确的视图,即使页面本身没有更新显示新视图.

更新 3

我已经尝试了如何以编程方式设置视图的各种组合,但我尝试过的任何方法都没有奏效.我是否使用服务器来获取视图、函数、直接 $scope 变量,什么都没有.变量本身是正确的,但是当我改变变量时,视图不会改变.

奇怪的是,当我在 init() 函数中设置 currentView 的值时,它只工作一次.如果我将值更改为代码本身中的下一个视图之一($scope.currentView = 'general' <- 这显示常规页面),则它会起作用,但如果我单击按钮将 currentView 更改为 'general'.

我尝试了各种 $scope.$applys、$digests 和 $timeouts.我所做的任何事情都不会让视图本身更新.唯一剩下的就是用 ng-show/hide 把它变成一堆 div,这真的很难看,而且很难管理,这也是我最初想使用视图的原因.

更新 4

仍然没有进展,无论我尝试什么......我认为将变量更改包装在 $timeout 中的一些奇怪的组合可能会证明有用,但唉,什么都没有.我的最后一个想法是将所有这些更改为它们自己的独立状态,但是我最终会得到一堆重复的代码,这显然不好.我在我的应用程序的其他部分使用了几乎相同类型的更改(尽管更改状态,而不是视图),并且它运行良好.我不明白为什么我不能动态改变视图.任何帮助将不胜感激.

更新 5

在下面的用户评论后有一些家,但无济于事.我试图调用各种 $state 更改来刷新视图,但没有任何效果.我尝试了以下所有方法,但都没有对页面产生任何影响:

$state.reload();$state.go($state.current, {}, { reload: true });$state.transitionTo($state.current, $stateParams, {重新加载:真的,继承:假,通知:真实});

解决方案

所以我解决了这个问题,只是让每个演练页面都从父演练中继承了自己的状态,每个页面都有一个视图.可能不是最好的方法,但我不想在这上面浪费更多时间.

我仍然喜欢一种仅使用嵌套视图并以这种方式导航的方法,因为将来使用该方法添加更多内容会更容易,而不会使我的 stateProvider 膨胀.

 .state('演练', {网址:'/演练',意见:{'':{templateUrl: 'app/walkthrough/walkthrough.html',控制器:'walkthroughController'}}}).state('walkthrough.welcome', {网址:'/欢迎',意见:{'walkthrough.welcome@walkthrough':{templateUrl: 'app/walkthrough/welcome.html'}}}).state('walkthrough.general', {网址:'/一般',意见:{'walkthrough.general@walkthrough':{templateUrl: 'app/walkthrough/general.html'}}}).state('walkthrough.business', {网址:'/业务',意见:{'walkthrough.business@walkthrough':{templateUrl: 'app/walkthrough/business.html'}}}).state('walkthrough.friends', {网址:'/朋友',意见:{'walkthrough.friends@walkthrough':{templateUrl: 'app/walkthrough/friends.html'}}})

现在我可以很容易地使用

I have a walkthrough in my app which comprises 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 = 'welcome';
};
_init();

$scope.setView = function (view) {
    $scope.currentView = view;
};

My state definition:

.state('walkthrough', {
    url: '/walkthrough',
    views: {
        '': {
            templateUrl: 'app/walkthrough/walkthrough.html',
            controller: 'walkthroughController'
        },
        'welcome@walkthrough': {
            templateUrl: 'app/walkthrough/welcome.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:

  1. Changing currentView to a getter function getCurrentView() which returns the currentView. Same behavior.
  2. Wrapping the currentView setter in a $scope.$apply. Get the $apply already in progress error
  3. 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 combination 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 combination 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 comment 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
});

解决方案

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.welcome', {
            url: '/welcome',
            views: {
                'walkthrough.welcome@walkthrough': {
                    templateUrl: 'app/walkthrough/welcome.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" />

这篇关于在 AngularJS UI-Router 中动态改变视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆