GVKun编程网logo

AngularJS页面访问时出现页面闪烁问题的解决(angularjs跳转页面)

27

针对AngularJS页面访问时出现页面闪烁问题的解决和angularjs跳转页面这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Angular.js中处理页面闪烁的方法详解、angular

针对AngularJS页面访问时出现页面闪烁问题的解决angularjs跳转页面这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Angular.js中处理页面闪烁的方法详解、angularjs – 使用Angular Dart中的单选按钮时出现问题、AngularJS 多指令Scope问题的解决、AngularJS 防止页面闪烁的方法等相关知识,希望可以帮助到你。

本文目录一览:

AngularJS页面访问时出现页面闪烁问题的解决(angularjs跳转页面)

AngularJS页面访问时出现页面闪烁问题的解决(angularjs跳转页面)

我们知道在应用的页面或者组件需要加载数据时,浏览器和angular渲染页面都需要消耗一定的时间。这里的间隔可能很小,甚至让人感觉不到区别;但也可能很长,这样会导致让我们的用户看到了没有被渲染过的页面。

这种情况被叫做Flash Of Unrendered Content (FOUC)(K)?and is always unwanted.下面我们将要介绍几个不同的方式防止这种情况发生在我们的用户身上。

1、ng-cloak

ng-cloak指令是angular的内置指令,它的作用是隐藏所有被它包含的元素:

rush:js;">

Hello {{ name }}

Ng-cloak实现原理为一个directive,页面初始化是在DOM的heade增加一行CSS代码,如下:

rush:js;">

[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{

display:none ! important;

}

<pre class= “prettyprint linenums”>

[ng\:cloak],.x-ng-cloak{

display:none ! important;

}

Angular将带有ng-cloak的元素设置为display:none.

在等到angular解析到带有ng-cloak节点的时候,会把元素上ng-cloak attribute和calss同时remove掉,这样就防止了节点的闪烁。如下:

rush:js;">

2、ng-bind

ng-bind是angular里面另一个内置的用于操作绑定页面数据的指令。我们可以使用ng-bind代替{{ }}的形式绑定元素到页面上;

使用ng-bind替代{{ }}可以防止未被渲染的{{ }}就展示给用户了,使用ng-bind渲染的空元素替代{{ }}会显得友好很多。

上面的例子可以重写成下面那样,这样就可以防止页面出现{{ }}了

rush:js;">

Hello

3、resolve

当在不同的页面之间使用routes(路由)的时候,我们有另外的方式防止页面在数据被完全加载到route之前被渲染。

在route(路由)里使用resolve可以让我们在route(路由)被完全加载之前获取我们需要加载的数据。当数据被加载成功之后,路由就会改变而页面也会呈现给用户;数据没有被加载成功route就不会改变, the $routeChangeError event will get fired.【$routeChangeError事件就(不)会被激活?】

rush:js;"> angular.module('myApp',['ngRoute']) .config(function($routeProvider) { $routeProvider .when('/account',{ controller: 'AccountCtrl',templateUrl: 'views/account.html',resolve: { // We specify a promise to be resolved account: function($q) { var d = $q.defer(); $timeout(function() { d.resolve({ id: 1,name: 'Ari Lerner' }) },1000); return d.promise; } } }) });

resolve 项需要一个key/value对象,key是resolve依赖的名称,value可以是一个字符串(as a service)或者一个返回依赖的方法。

resolve is very useful when the resolve value returns a promise that becomes resolved or rejected.

当路由加载的时候,resolve参数里的keys可以作为可注入的依赖:

rush:js;"> angular.module('myApp') .controller('AccountCtrl',function($scope,account) { $scope.account = account; });

我们同样可以使用resolve key传递$http方法返回的结果,as $http returns promises from it's method calls:

rush:js;"> angular.module('myApp',resolve: { account: function($http) { return $http.get('http://example.com/account.json') } } }) });

推荐定义一个独立的service的方式来使用resolve key,并且使用service来相应返回所需的数据(这种方式更容易测试)。要这样处理的话,我们需要创建一个service:

首先,看一下accountService,

rush:js;"> angular.module('app') .factory('accountService',function($http,$q) { return { getAccount: function() { var d = $q.defer(); $http.get('/account') .then(function(response) { d.resolve(response.data) },function err(reason) { d.reject(reason); }); return d.promise; } } })

定义好service之后我们就可以使用这个service来替换上面代码中直接调用$http的方式了:

rush:js;"> angular.module('myApp',resolve: { // We specify a promise to be resolved account: function(accountService) { return accountService.getAccount() } } }) });

Angular.js中处理页面闪烁的方法详解

Angular.js中处理页面闪烁的方法详解

前言

大家在使用{{}}绑定数据的时候,页面加载会出现满屏尽是{{xxx}}的情况。数据还没响应,但页面已经渲染了。这是因为浏览器和angularjs渲染页面都需要消耗一定的时间,这个间隔可能很小,甚至让人感觉不到,这种情况一切正常,但这个时间也可能很长,这时候用户可能会看到满屏尽是{{xxxx}}。这种情况被叫做“Flash Of Unrendered Content (FOUC)(K)?and is always unwanted.”。

问题

为了图方便,我们很喜欢使用下面的做法

 <div>
 {{name}}
 </div>

但这也为满屏尽是{{}}埋下了坑。当接口,网络响应速度够快的情况下,很难发现这个问题,但放在移动端4g或者网络环境更差的情况下,这个问题就会频发。

解决办法

1、ng-cloak

该指令是angularjs的内置的指令,它的作用是隐藏所有被它包含的元素。在浏览器加载和编译渲染完成后,angularjs会自动删除ngCloak元素属性,这样这个元素就会变为可见的。

 <div ng-cloak>
 {{name}}
 </div>

2、ng-bind

该指令是angularjs内置的用于绑定页面数据的指令。可以使用该指令代替{{}}的方式绑定数据到页面上。使用ng-bind可以防止未被渲染的{{}}展示给用户。如下所示:

 <div ng-bind="name"> 
 </div>

3、resolve

当使用routes路由的时候,resolve可以防止我们在route路由被完全加载之前获取我们需要加载的数据,当数据被加载成功之后,路由再改变而页面也会呈现给用户,数据没有加载成功route不会改变。

可以参考:https://www.jb51.net/article/80523.htm

angular.module(''myApp'', [''ngRoute''])
.config(function($routeProvider) {
 $routeProvider
 .when(''/account'', {
 controller: ''AccountCtrl'',
 templateUrl: ''views/account.html'',
 resolve: {
 // We specify a promise to be resolved
 account: function($q) {
 var d = $q.defer();
 $timeout(function() {
 d.resolve({
 id: 1,
 name: ''Ari Lerner''
 })
 }, 1000);
 return d.promise;
 }
 }
 })
});

resolve 项需要一个key/value对象,key是resolve依赖的名称,value可以是一个字符串(as a service)或者一个返回依赖的方法。

resolve is very useful when the resolve value returns a promise that becomes resolved or rejected.

当路由加载的时候,resolve参数里的keys可以作为可注入的依赖:

ngular.module(''myApp'')
.controller(''AccountCtrl'', 
 function($scope, account) {
 $scope.account = account;
});

我们同样可以使用resolve key传递$http方法返回的结果,as $http returns promises from it''s method calls:

angular.module(''myApp'', [''ngRoute''])
.config(function($routeProvider) {
 $routeProvider
 .when(''/account'', {
 controller: ''AccountCtrl'',
 templateUrl: ''views/account.html'',
 resolve: {
 account: function($http) {
 return $http.get(''http://example.com/account.json'')
 }
 }
 })

推荐定义一个独立的service的方式来使用resolve key,并且使用service来相应返回所需的数据(这种方式更容易测试)。要这样处理的话,我们需要创建一个service:

首先,看一下accountService,

angular.module(''app'')
.factory(''accountService'', function($http, $q) {
 return {
 getAccount: function() {
 var d = $q.defer();
 $http.get(''/account'')
 .then(function(response) {
 d.resolve(response.data)
 }, function err(reason) {
 d.reject(reason);
 });
 return d.promise;
 }
 }
})

定义好service之后我们就可以使用这个service来替换上面代码中直接调用$http的方式了:

ngular.module(''myApp'', [''ngRoute''])
.config(function($routeProvider) {
 $routeProvider
 .when(''/account'', {
 controller: ''AccountCtrl'',
 templateUrl: ''views/account.html'',
 resolve: {
 // We specify a promise to be resolved
 account: function(accountService) {
 return accountService.getAccount()
 }
 }
 })

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。

您可能感兴趣的文章:
  • AngularJS页面访问时出现页面闪烁问题的解决
  • Angularjs在初始化未完毕时出现闪烁问题的解决方法分析
  • AngularJS使用ng-Cloak阻止初始化闪烁问题的方法

angularjs – 使用Angular Dart中的单选按钮时出现问题

angularjs – 使用Angular Dart中的单选按钮时出现问题

我可以使单选按钮工作并绑定到模型.但是,当页面加载时,即使有一个单选按钮,也没有显示选中的单选按钮.

这是Dart代码:

import 'package:angular/angular.dart';

@NgDirective(
  selector: '[my-controller]',publishAs: 'ctrl'
)
class MyController {
  List<String> fruits = ['apple','banana','kiwi'];
  String favorite;

  MyController() {
    favorite = fruits[1];
  }
}

main() {
  ngBootstrap(module: new Module()..type(MyController));
}

这是视图标记.一旦我开始选择无线电,UI就会正确更新,数据绑定也能正常工作.但是在页面加载时没有选择任何内容.不知道为什么会这样.

<!DOCTYPE html>
<html ng-app>
  <body>
    <div my-controller>            
      <div ng-repeat="fruit in ctrl.fruits">
        <input type="radio"
            name="fruits"
            ng-model="ctrl.favorite" 
            value="{{fruit}}">{{fruit}}
      </div>
      <div>{{ctrl.favorite}} is my favorite</div>
    </div>

    <script type="application/dart" src="main.dart"></script>
    <script type="text/javascript" src="packages/browser/dart.js"></script>
  </body>
</html>
我试过你的代码.经过一些实验后,我看到切换属性ng-model和value的顺序解决了问题.我认为这是一个错误.
<!DOCTYPE html>
<html ng-app>
  <body>
    <div my-controller>
      <div ng-repeat="fruit in ctrl.fruits">
        <input type="radio"
            name="fruits"
            value="{{fruit}}"
            ng-model="ctrl.favorite"
            >{{fruit}}</div>
      <div>{{ctrl.favorite}} is my favorite</div>
    </div>

    <script type="application/dart" src="main.dart"></script>
    <script type="text/javascript" src="packages/browser/dart.js"></script>
  </body>
</html>

AngularJS 多指令Scope问题的解决

AngularJS 多指令Scope问题的解决

问题描述

不确定度指令,传入参量类别,然后该指令列出该类别下的所有不确定度。

新增页面用到了三个该指令,只有最后一个成功,前两个都没有数据。

探究源码

以下是指令源码:

''use strict'';

/**
 * @ngdoc directive
 * @name webappApp.directive:yunzhiAccuracyUncertainty
 * @description
 * # yunzhiAccuracyUncertainty
 * 不确定度指令
 * zhangxishuo
 */
angular.module(''webappApp'')
 .directive(''yunzhiAccuracyUncertainty'', function($filter) {
  return {
   templateUrl: ''views/directive/yunzhiAccuracyUncertainty.html'',
   restrict: ''E'',
   scope: {
    parameterCategory: ''='',   // 参量类别
    ngModel: ''=''     // 不确定度
   },
   link: function postLink(scope, element, attrs) {
    var self = this;

    // 初始化
    self.init = function() {
     // 初始化不确定度空列表
     scope.accuracyList = [];
     // 监听参量类别
     scope.$watch(''parameterCategory'', self.watchParameterCategory);
     // 监听不确定度
     scope.$watch(''ngModel'', self.watchNgModel);
    };

    // 监听参量类别
    self.watchParameterCategory = function(newValue) {
     if (newValue && newValue.id) {
      // 设置不确定度列表
      scope.accuracyList = newValue.accuracyUncertaintyList;
      // 过滤数据
      self.filter();
     }
    };

    // 监听不确定度
    self.watchNgModel = function(newValue) {
     if (newValue && newValue.id) {
      // 设置默认选中
      scope.selected = newValue;
     }
    };

    // 过滤数据
    self.filter = function() {
     angular.forEach(scope.accuracyList, function(accuracy) {
      // 过滤不确定度
      accuracy._value = $filter(''yunzhiAccuracyWithUnit'')(accuracy);
     });
    };

    // 更新模型
    self.updateModel = function(selected) {
     // 更新数据
     scope.ngModel = selected;
    };

    // 传给视图
    scope.updateModel = self.updateModel;

    self.init();
   }
  };
 });

尝试

尝试打印了一下scope.accuracyList,果然有问题。

前两个都是空,最后一个数组有值。

想不明白,这里明明监听参量类别,并将scopeaccuracyList设置了值啊?为什么没有呢?

scope

尝试打印一下scope

去关注scope$id就行了。

依次打印的是:

504
508   // 第一个指令
506
508   // 第二个指令
508
508   // 第三个指令

前两个指令执行时赋值的是一个scope,而过滤的又是另一个scope,所以过滤不出数据,最后一个是同一scope,所以正常输出。

原因

官方文档

HTML Compiler - AngularJS

HTML Compiler允许开发者教会浏览器一些新的语法,AngularJS称这个为指令。

Compiler是一个遍历DOM去搜寻属性的AngularJS服务,编译分为以下两个阶段。

  • Compile:遍历DOM并收集所有的指令,返回结果是一个linking函数。
  • Link:使用scope整合指令并产生动态视图,任何scope模型上的改变都会反映到视图上,任何视图上的用户交互也会反映到scope模型上。

指令如何编译

AngularJS操作DOM节点而不是字符串,这很重要。但通常,你不需要关注这个,因为当页面加载时,浏览器会自动把HTML转换为DOM

指令编译有以下三阶段:

  • $compile遍历DOM并匹配指令,如果compiler发现有匹配指令的元素,就会将该指令添加到指令列表中。一个元素可能匹配多个指令。
  • 一旦所有匹配DOM元素的指令都被确定,然后compiler会根据优先级对指令进行排序。每一个指令的compile函数都会被执行,每一个compile函数都有操作DOM的机会。compile会返回link函数,这些函数被组合成一个“组合的”link函数,它能调用每个指令返回的link函数。
  • $compile会调用上一步中的“组合的”link函数来链接scope和模板。

下面是官方的示意代码:

// HTML字符串
var html = ''<div ng-bind="exp"></div>'';

// 将HTML字符串转换为DOM模板
var template = angular.element(html);

// 编译DOM模板返回link函数
var linkFn = $compile(template);

// 将编译后的模板与scope链接
var element = linkFn(scope);

// 添加到DOM中
parent.appendChild(element);

分析

compile只在编译时执行一次,只要页面中存在一个该指令,该指令的link方法就执行一次。

所以,AngularJS使用$compile编译我的指令,然后看我页面中用到了三个该指令,并且都是独立scope,所以就创建了三个scope

然后使用这三个scope去调用link函数。

前面已经提到,AngularJS会将link函数统一组合成一个“组合的”link函数,所以我们可以猜想,组合函数中的link函数的数量与指令的数量一致,所以三次调用的是一个link函数,link函数只有一个实例!

linkFn(scope)

scope传进去作为link函数的入参。

上面的事件监听都是没毛病的,将传入的scope绑定到视图,然后添加到DOM中,然后就与这个link函数无关了。

但是这个filter就不行了。

第一个scope调用,filter功能是过滤第一个scopeaccuracyList,第二个scope调用,filter功能是过滤第二个scopeaccuracyList

所以第三次执行时,第三个scope将之前的两个都覆盖了,link函数中的filter的作用变成了过滤最后一个scopeaccuracyList

<!-- 不确定度 -->
<ui-select ng-model="selected" theme="bootstrap" ng-change="updateModel(selected)">
 <ui-select-match placeholder="请选择">
  {{ $select.selected._value }}
 </ui-select-match>
 <ui-select-choices repeat="accuracy in accuracyList">
  <div ng-bind-html="accuracy._value"></div>
 </ui-select-choices>
</ui-select>

所以这里下拉框显示的是不确定度过滤后的_value的值,这里的空字符串看起来不明显,加上test测试一下。

所以,这块视图绑定的scope是正确的,只是时间监听之后去过滤数据,因为过滤的并不是当前scope的数据,所以accuracy._value就没有值,是undefined,所以显示一个空的字符串。

解决方案

明白了原理之后解决问题自然易如反掌,只需将filterscope独立即可,这样就不受每次执行不同scope的影响了。

总结

很多东西,书上是没有的,需要我们自己去发现,去分析,去解决。

翻开了之前遇到指令编译问题时从别人博客里学习来的手动编译方法。

angular.module(''webappApp'')
 .directive(''reCompile'', function($compile) {
  return {
   restrict: ''A'',
   link: function postLink(scope, element, attrs) {
    // 监听使用该指令的元素上的ngBindHtml
    attrs.$observe(''ngBindHtml'', function() {
     // 如果元素使用了ngBindHtml指令
     if (attrs.ngBindHtml) {
      // 重新编译
      $compile(element[0].children)(scope);
     }
    });
   }
  };
 });

记得之前的需求是,数据经过过滤器过滤,返回的是一段HTML代码,虽然使用ng-bind-html能将该段代码添加到DOM中,但是这段代码中有指令,因为该指令不是初始时就有的,所以,这个指令是不会被编译的。

所以需要编写一个重新编译的指令,手动编译动态创建的指令。

记得当时,看这段代码也不是那么完全理解,现在学习完指令的编译之后,再去翻看之前的代码,一切原来是如此简单。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:
  • Spring Cloud @RefreshScope 原理及使用
  • 如何在Spring中自定义scope的方法示例
  • spring boot补习系列之几种scope详解
  • 浅谈spring中scope作用域
  • vue组件中的样式属性scoped实例详解
  • WPF中NameScope的查找规则详解
  • Spring注解@Scope原理及用法解析

AngularJS 防止页面闪烁的方法

AngularJS 防止页面闪烁的方法

我们知道在应用的页面或者组件需要加载数据时,浏览器和angular渲染页面都需要消耗一定的时间。这里的间隔可能很小,甚至让人感觉不到区别;但也可能很长,这样会导致让我们的用户看到了没有被渲染过的页面。

这种情况被叫做Flash Of Unrendered Content (FOUC)(K)?and is always unwanted.下面我们将要介绍几个不同的方式防止这种情况发生在我们的用户身上。

1、ng-cloak

ng-cloak指令是angular的内置指令,它的作用是隐藏所有被它包含的元素:

<div ng-cloak>
 <h1>Hello {{ name }}</h1>
</div>

在浏览器加载和编译渲染完成之后,angular会自动删除ngCloak元素属性,这样这个元素就会变成可见的。

在IE7里面使用ng-cloak的安全方式是给元素多加一个ng-cloak class

<div ng-cloak>
 <h1>Hello {{ name }}</h1>
</div>

2、ng-bind

ng-bind是angular里面另一个内置的用于操作绑定页面数据的指令。我们可以使用ng-bind代替{{ }}的形式绑定元素到页面上;

使用ng-bind替代{{  }}可以防止未被渲染的{{ }}就展示给用户了,使用ng-bind渲染的空元素替代{{ }}会显得友好很多。

上面的例子可以重写成下面那样,这样就可以防止页面出现{{ }}了

<div>
 <h1>Hello <span ng-bind="name"></span></h1>
</div>

3、resolve

当在不同的页面之间使用routes(路由)的时候,我们有另外的方式防止页面在数据被完全加载到route之前被渲染。

在route(路由)里使用resolve可以让我们在route(路由)被完全加载之前获取我们需要加载的数据。当数据被加载成功之后,路由就会改变而页面也会呈现给用户;数据没有被加载成功route就不会改变, the $routeChangeError event will get fired.【$routeChangeError事件就(不)会被激活?】

angular.module(''myApp'', [''ngRoute''])
.config(function($routeProvider) {
 $routeProvider
 .when(''/account'', {
  controller: ''AccountCtrl'',
  templateUrl: ''views/account.html'',
  resolve: {
   // We specify a promise to be resolved
   account: function($q) {
    var d = $q.defer();
    $timeout(function() {
     d.resolve({
      id: 1,
      name: ''Ari Lerner''
     })
    }, 1000);
    return d.promise;
   }
  }
 })
});

resolve 项需要一个key/value对象,key是resolve依赖的名称,value可以是一个字符串(as a service)或者一个返回依赖的方法。

resolve is very useful when the resolve value returns a promise that becomes resolved or rejected.

当路由加载的时候,resolve参数里的keys可以作为可注入的依赖:

angular.module(''myApp'')
.controller(''AccountCtrl'', 
 function($scope, account) {
  $scope.account = account;
});

我们同样可以使用resolve key传递$http方法返回的结果,as $http returns promises from it''s method calls:

angular.module(''myApp'', [''ngRoute''])
.config(function($routeProvider) {
 $routeProvider
 .when(''/account'', {
  controller: ''AccountCtrl'',
  templateUrl: ''views/account.html'',
  resolve: {
   account: function($http) {
    return $http.get(''http://example.com/account.json'')
   }
  }
 })
});

推荐定义一个独立的service的方式来使用resolve key,并且使用service来相应返回所需的数据(这种方式更容易测试)。要这样处理的话,我们需要创建一个service:

首先,看一下accountService,

angular.module(''app'')
.factory(''accountService'', function($http, $q) {
 return {
  getAccount: function() {
   var d = $q.defer();
   $http.get(''/account'')
   .then(function(response) {
    d.resolve(response.data)
   }, function err(reason) {
    d.reject(reason);
   });
   return d.promise;
  }
 }
})

定义好service之后我们就可以使用这个service来替换上面代码中直接调用$http的方式了:

angular.module(''myApp'', [''ngRoute''])
.config(function($routeProvider) {
 $routeProvider
 .when(''/account'', {
  controller: ''AccountCtrl'',
  templateUrl: ''views/account.html'',
  resolve: {
   // We specify a promise to be resolved
   account: function(accountService) {
    return accountService.getAccount()
   }
  }
 })
});

以上所述是小编给大家介绍的AngularJS 防止页面闪烁的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

您可能感兴趣的文章:
  • Angularjs处理页面闪烁的解决方法
  • AngularJS页面访问时出现页面闪烁问题的解决
  • AngularJS使用ng-Cloak阻止初始化闪烁问题的方法
  • Angularjs在初始化未完毕时出现闪烁问题的解决方法分析

今天关于AngularJS页面访问时出现页面闪烁问题的解决angularjs跳转页面的讲解已经结束,谢谢您的阅读,如果想了解更多关于Angular.js中处理页面闪烁的方法详解、angularjs – 使用Angular Dart中的单选按钮时出现问题、AngularJS 多指令Scope问题的解决、AngularJS 防止页面闪烁的方法的相关知识,请在本站搜索。

本文标签: