不同UI-路由状态下的不同页面背景

6
在一个简化的场景中,我有两个UI-Router状态,并希望为它们设置不同的页面背景颜色。
理想情况下,我想要做到以下几点:
<body ng-class="background" ui-view>
</body>

然后在状态控制器中设置背景类(可能是动态的,即:在控制器中计算):

stateHelperProvider
    .state({
        name: 'a',
        url: '/a',
        templateUrl: 'views/a.html',
        controller: function ($scope) {
            $scope.background = 'bg1';
        }
    })
    .state({
        name: 'b',
        url: '/b',
        templateUrl: 'views/b.html',
        controller: function ($scope) {
            $scope.background = 'bg2';
        }
    });

但是在body标签上使用ui-view属性会导致其被删除。因此,我必须将ui-view属性放在body内的一个div上。

<body>
    <div ui-view></div>
</body>

如何控制页面的背景颜色?

我知道有一些方法可以实现(例如在UI-Router的onEnter函数中访问body的class DOM属性...),但是否有更好的方法呢?

或者只需要将div[ui-view]设置为全屏高度(这不是一个简单的任务(链接)),并在该元素上设置背景以模仿应用于body时占用整个视口的背景效果(链接)

2个回答

2
总结一下我的学习,有两种方法可以做到这一点。两种方法都要求$rootScope中存在$state服务。这种方法的优雅性可能会引起争议, 但我会选择这个解决方案。
  1. 如果背景类仅依赖于状态,则将它们添加到状态的自定义数据中:

示例代码:

.state({
    ...,
    data: {
        bodyClass: 'bg1'
    }
});

然后,在HTML标记中添加ng-class,并引用当前状态的数据:
<body ng-class="$state.current.data.bodyClass">

如果背景类(除了状态外)依赖于其他东西(如状态参数或服务等),请使用状态的解析机制
示例代码:
.state({
    ...,
    resolve: {
        bodyClass: function($stateParams) {
            // do some calculation
            return ...
        }
    }
});

然后,在元素上加入 ng-class 并通过 $state.$current.locals.globals 引用已解析的类名:
<body ng-class="$state.$current.locals.globals.bodyClass">

在这两种情况下,bodyClass 可以是 ng-class 指令 中有效的任何内容。

顺便提一下,用于更新页面标题的Angular UI-Router标题插件在某种程度上做了类似的事情。插件链接:https://github.com/nonplus/angular-ui-router-title,相关代码链接:https://github.com/nonplus/angular-ui-router-title/blob/master/src/angular-ui-router-title.js#L6 - jack_kerouac
1
这对我有用!--只想指出为了使其工作,您必须在声明模块时从内部运行$rootScope.$state = $state;。这在答案的第一句中提到并加粗显示,但没有给出示例。您可以通过访问此链接https://dev59.com/ZHbZa4cB1Zd3GeqPFGBI找到示例代码,该链接也在答案中提供。 - Benjamin Conant

0

这可能不是很准确,但是您可以在控制器中直接更改您的 body 背景颜色吗?

stateHelperProvider
    .state({
        name: 'a',
        url: '/a',
        templateUrl: 'views/a.html',
        controller: function ($scope) {
            document.body.style.background = 'bg1';
        }
    })
    .state({
        name: 'b',
        url: '/b',
        templateUrl: 'views/b.html',
        controller: function ($scope) {
            document.body.style.background = 'bg2';
        }
    });

或者在这种情况下,只需向 body 添加/删除 CSS 类?

祝你好运。


这个方案在使用类时可能可行。问题是,如果我有一个没有背景的状态 c,那么上一个状态的背景将保留下来。当然,我可以在作用域上监听 $destroy 事件,但这并不是特别优雅的解决方案。 - jack_kerouac
一个控制器放在身体上,使用'ngStyle'获取页面值,并根据页面名称的条件改变背景色怎么样?可能不是很准确,但希望能有所帮助。 - Alexis B.
我可以将背景类作为状态的自定义数据属性,然后像这样做:<body ng-class="$state.current.data.backgroundClass">,其中 $state$rootScope 上。虽然不完全是您提出的方案,但受其启发。 - jack_kerouac
我曾经考虑过那样的事情,但现在想法更好了。:) - Alexis B.
我刚意识到实际上我有一个需要动态计算背景CSS类的要求,这意味着它需要在控制器或解析器中。正如这个回答所详细说明的那样,有一种方法可以从 $state 访问已解析的属性。因此,那可能是可行的方法。 - jack_kerouac
我甚至不知道这是可能的。太好了,谢谢分享。 - Alexis B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接