【问题标题】:AngularJS : dynamic stylesheet link tag fires request too soonAngularJS:动态样式表链接标签过早触发请求
【发布时间】:2013-09-02 02:13:21
【问题描述】:

我面临的问题与Conditionally-rendering css in html head 中描述的问题相似(但不完全相同,请耐心等待)

我也在“懒惰地”加载样式表,从我在控制器一开始初始化的范围变量中获取文件名:

<link rel="stylesheet" data-ng-href="css/{{ filename }}.css" />

由于我使用的是ng-href(此处为data- 形式),我确实在避免不需要的请求,例如:

http://localhost/css/%7B%7B%20filename%7D%7D.css

但这一切仍然太快了,我几乎每次都得到这个:

http://localhost/css/.css

这似乎意味着请求在 Angular 删除它自己的标记的那一刻和它用正确的值替换它的那一刻之间触发(稍后它会这样做,然后我的样式表加载适当地)。我想这根本不可能……!?

我想我可能为 filename 范围变量提供值太晚了,但正如我所说,这是我的控制器中完成的第一件事:

angular.module('myControllers', [])
    .controller('TestCtrl', ['$scope', function($scope) {
        $scope.filename = 'test';

        // some more code...
    }]);

我正在使用 Angular 1.1.5 ;我能做些什么吗?这没什么大不了的,但如果我能解决它仍然会更好。

编辑:这里是完整的代码,根据要求。我不会包含页面模板,因为它们与问题无关。

index.html:

<!DOCTYPE html>
<html lang="en" data-ng-app="myapp">

<head>
    <meta charset="utf-8" />
    <title>My App</title>
    <link rel="stylesheet" data-ng-href="/assets/css/{{ filename }}.css" />
</head>

<body>
    <div id="app" class="app" style="display: none;" data-ng-view></div>

    <script src="/assets/js/lib/angular/angular.min.js"></script>
    <script src="/assets/js/app/app.js"></script>
    <script src="/assets/js/app/controllers.js"></script>
</body>

</html>

app.js:

var app = angular.module('myapp', ['myControllers'])
    .config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
        $locationProvider.hashPrefix('!');
        $routeProvider

        .when('/', {
            templateUrl: 'path/to/my/template.html',
            controller: 'TestCtrl'
        })

        .otherwise({ redirectTo: '/' });
    }]);

app.run();

controllers.js:

angular.module('myControllers', [])
    .controller('TestCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
        $rootScope.filename = 'stylesheet';
    }]);

(是的,我尝试使用一个空控制器,就像这个一样,同样的问题。)

【问题讨论】:

  • 这种行为是否也发生在体内?你确定这是头颅吗?
  • @Phix :我只是尝试将链接标签移动到正文中,行为完全相同。
  • 您的控制器范围在您的标记中绑定在哪里?
  • @AndréDion:你的意思是使用 ngController 吗?我在应用程序中有两个控制器,所以我没有使用这个指令(控制器通过 $routeProvider 绑定)。抱歉,我还在探索 Angular,所以我的回答可能不对……?
  • 您可以使用ng-controller 指令或$routeProvider 配置绑定您的控制器范围。我对 Angular 也很熟悉,但我怀疑您的 &lt;link&gt; 元素实际上并不是控制器范围的一部分。 {{filename}} 是否曾经扩展为正确的值?

标签: javascript css angularjs


【解决方案1】:

在一个小例子中对我有用。

那个算法:

attr.$observe(normalized, function(value) {
      if (!value)
         return;

      attr.$set(attrName, value);

      // on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
      // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
      // to set the property as well to achieve the desired effect.
      // we use attr[attrName] value since $set can sanitize the url.
      if (msie) element.prop(attrName, attr[attrName]);
    });

如果该值为 false,则该函数立即返回,例如未定义。

你能发布完整的代码吗? 这应该是另一个问题。

编辑:

通过 Route-Provider 绑定控制器只会将此控制器绑定到带有 ng-view 元素的元素。

你可以这样做:

HTML:

<head ng-controller="HeadCtrl">
<link rel="stylesheet" data-ng-href="{{ filename }}.css">
</head>

JS:

app.controller("HeadCtrl",function ($scope)
{
$scope.filename = 'apartment';
});

【讨论】:

  • 不错的一个。问题是我可以有多个控制器,每个控制器都会带来自己的样式表(因为我在每个控制器中为文件名变量提供了正确的值)。因此,在我的情况下,处理此问题的单独控制器看起来并不好。但是范围确实是一个问题,这就是我实际使用 $rootScope 的原因(参见我通过编辑帖子添加的完整代码)。
  • @neemzy 如果是这种情况,请按照 Robin 的建议保留 HeadCtrl 并创建一个服务,控制器可以使用该服务在服务上设置属性。在Sharing Data between Controllers观看此视频。
  • @AndréDion 感谢您的链接!我仍然有同样的问题,所以我不相信它与范围相关(使用 $rootScope 几乎可以避免这种问题,即使它确实是一种肮脏的方式)。
【解决方案2】:

顺便说一句

ng-cloak 不会“触发”来隐藏某些东西。 您必须为其添加一个 CSS 类。

http://docs.angularjs.org/api/ng.directive:ngCloak

[ng\:cloak], 
[ng-cloak], 
[data-ng-cloak], 
[x-ng-cloak], 
.ng-cloak, 
.x-ng-cloak {
   display: none !important;
}

请不要内联 css :)

它是一个简单的指令,当 Angular 完成加载并开始解释指令时删除 ng-cloak 属性。

然后您的代码通过正常的浏览器呈现机制切换为可见。

【讨论】:

  • 哈哈,我也不喜欢内联 CSS。我将直接使用类语法再试一次。
  • 我又试了一次,还是不行。我所有的 JS 都在正文的底部,所以我的标记在它被执行之前被渲染并且 ng-cloak 类意味着任何东西,这可能是为什么?
【解决方案3】:

我通过将ngIf 指令添加到link 标记来解决它,因此直到filename 不虚假才会呈现它。我知道有点脏,但它确实有效!

<link rel="stylesheet" data-ng-if="filename" data-ng-href="css/{{ filename }}.css" />

【讨论】:

    猜你喜欢
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 2020-10-30
    相关资源
    最近更新 更多