首页
在线工具
搜索
1
Kuboard与KubeSphere的区别:Kubernetes管理平台对比
2
ShardingSphere使用中的重点问题剖析
3
Flowable工作流引擎源码深度解析
4
用AI生成的原型设计稿效果还可以
5
如何将Virtualbox和VMware虚拟机相互转换
杂谈与随笔
工具与效率
源码阅读
技术管理
运维
数据库
前端开发
后端开发
Search
标签搜索
Angular
Docker
Phabricator
SpringBoot
Java
Chrome
SpringSecurity
SpringCloud
DDD
Git
Mac
K8S
Kubernetes
ESLint
SSH
高并发
Eclipse
Javascript
Vim
Centos
Jonathan
累计撰写
86
篇文章
累计收到
0
条评论
首页
栏目
杂谈与随笔
工具与效率
源码阅读
技术管理
运维
数据库
前端开发
后端开发
页面
搜索到
8
篇与
的结果
2016-11-02
Angular2学习笔记
Angular2学习笔记 模板语法 模板是包在反引号 (`) 中的一个多行字符串。反引号 (`) ——注意,不是单引号 (') ——有很多好用的特性,比如允许多行字符串和模板字面量。 装饰器 @Component 装饰器,这个装饰器类(和我们随后将会学到的 @Directive 和 @Pipe 一样)是 InjectableMetadata 的子类型。实际上,这个 InjectableMetadata 装饰器是把一个类标识为依赖注入器实例化的目标。 TypeScript接口 接口只是 TypeScript 的一个设计期概念。JavaScript 没有接口。在生成 JavaScript 代码时,TypeScript 的接口就消失了。在运行期,没有接口类型信息可供 Angular 查找。 HTML Attribute 与 DOM Property Attribute 是由 HTML 定义的。Property 是由 DOM(Document Object Model) 定义的。 就算名字相同,HTML Attribute 和 DOM Property 也不是同一样东西。 组件交互 组件定义了一个 deleteRequest 属性,它是一个 EventEmitter 实例。(译注:deleteRequest 属性是导出 Output 属性,是组件与父级组件交互的主要方式之一。参见 输入和输出属性 和 父组件监听子组件的事件。我们需要用 @Output() 来装饰它,或者把它添加到组件元数据的 outputs 数组中,它才能在父级组件可见。) NgFor 与 trackBy 现在,把 NgForTrackBy 指令设置为那个追踪函数: <div *ngFor="let hero of heroes; trackBy:trackByHeroes">({{hero.id}}) {{hero.fullName}}</div> 追踪函数不会排除所有 DOM 更改。如果用来判断是否同一个英雄的属性变化了,Angular 就可能不得不更新 DOM 元素。但是如果这个属性没有变化——而且大多数时候它们不会变化——Angular 就能留下这些 DOM 元素。列表界面就会更加平滑,提供更好的响应。 安全导航操作符 Angular 的安全导航操作符 (?.) 是一种流畅而便利的方式,用来保护出现在属性路径中 null 和 undefined 值。这意味着,当 currentHero 为空时,保护视图渲染器,让它免于失败。 其他重要概念 数据绑定 Angular 支持多种数据绑定形式: 插值表达式:{{value}} 属性绑定:[property]="value" 事件绑定:(event)="handler()" 双向绑定:[(ngModel)]="property" 指令 Angular 有三种类型的指令: 组件:带有模板的指令 结构型指令:改变 DOM 布局的指令(如 *ngIf、*ngFor) 属性型指令:改变元素、组件或其他指令的外观和行为的指令(如 ngClass、ngStyle) 服务与依赖注入 Angular 服务是一个广义的概念,它包括应用所需的任何值、函数或特性。通常是一个具有明确用途的类。服务通过依赖注入系统被注入到需要它们的组件中。 模块 Angular 应用是模块化的,它拥有自己的模块系统,称作 NgModule。每个 Angular 应用都至少有一个 NgModule 类,也就是根模块,它习惯上命名为 AppModule,并位于一个名叫 app.module.ts 的文件中。
2016年11月02日
2016-07-05
AngularJS 中的 $apply 和 $digest
AngularJS 中的 $apply 和 $digest 避免在控制器中使用 $watch 永远不要在控制器中使用 $watch,因为它会使控制器难以测试。Angular 提供了 $watchCollection 方法来对对象属性或数组元素设置浅监控,只要属性发生变化就会触发监听器回调。 $watchCollection 示例 $watchCollection() 函数也返回一个注销函数。调用这个注销函数时,也会取消集合上的监听。 手动调用 $apply() 如果你使用了 JavaScript 中的 setTimeout() 来更新一个 scope model,那么 AngularJS 就没有办法知道你更改了什么。这种情况下,调用 $apply() 是你的责任,通过调用它来触发一轮 $digest 循环。 示例代码 HTML <body ng-app="myApp"> <div ng-controller="MessageController"> Delayed Message: {{message}} </div> </body> JavaScript (不使用 $apply()) angular.module('myApp', []).controller('MessageController', function($scope) { $scope.getMessage = function() { setTimeout(function() { $scope.message = 'Fetched after 3 seconds'; console.log('message:' + $scope.message); }, 2000); } $scope.getMessage(); }); 这段代码会在控制台显示更新后的 model,但视图不会更新。 使用 $apply() 修改后的代码 angular.module('myApp', []).controller('MessageController', function($scope) { $scope.getMessage = function() { setTimeout(function() { $scope.$apply(function() { // wrapped this within $apply $scope.message = 'Fetched after 3 seconds'; console.log('message:' + $scope.message); }); }, 2000); } $scope.getMessage(); }); 现在视图会在两秒钟后更新。 注意: 应该使用 $timeout service 而不是 setTimeout(),因为前者会自动调用 $apply()。 $digest 循环 当 $digest 循环运行时,watchers 会被执行来检查 scope 中的 models 是否发生了变化。如果发生了变化,相应的 listener 函数就会被执行。为了处理 listener 函数可能修改 scope model 的情况,AngularJS 实现了脏检查机制(Dirty Checking)。这意味着 $digest 循环会持续运行直到 models 不再发生变化,或者循环次数达到10次。 结语 总是将要执行的代码和函数传递给 $apply 去执行。 使用 $apply 时,应该像下面这样: $scope.$apply(function() { $scope.variable1 = 'some value'; executeSomeAction(); }); 而不是这样: $scope.variable1 = 'some value'; executeSomeAction(); $scope.$apply(); 这两种方式虽然都能工作,但是第一个方法更安全,因为它能确保异常被正确捕获并处理。
2016年07月05日
2016-06-21
Angular-UI-Router 学习笔记
Angular-UI-Router 学习笔记 路由 (Route) 为什么用 Route AJAX 请求不会留下 History 记录 用户无法直接通过 URL 进入应用中的指定页面(无法保存书签、链接分享给朋友) AJAX 对 SEO 是个灾难 AngularJS 路由配置示例 var bookStoreApp = angular.module('bookStoreApp', [ 'ngRoute', 'ngAnimate', 'bookStoreCtrls', 'bookStoreFilters', 'bookStoreServices', 'bookStoreDirectives' ]); bookStoreApp.config( function($routeProvider) { $routeProvider .when('/hello', { templateUrl: 'tpls/hello.html', controller: 'HelloCtrl' }) .when('/list/:bookId', { templateUrl: 'tpls/bookList.html', controller: 'BookListCtrl' }) .otherwise({ redirectTo: '/hello' }); } ); 嵌套 View (Nested Routing for AngularJS) AngularUI-Router (AngularUI) <div ui-view></div> 前端路由的基本原理 哈希 (#) HTML5 中新的 history API 路由的核心 是给应用定义 "状态" 使用路由机制会影响应用的整体编码方式 (需预先定义好状态) 考虑兼容性问题与 "优雅降级" Angular-UI-Router ui-sref 指令 <a ui-sref="home">Home</a> <a ui-sref="about">About</a> <a ui-sref="contacts.list">Contacts</a> $state.includes 返回 true / false <li ng-class="{active: $state.includes('contacts')}"> <a ui-serif="contacts.list">Contacts</a> </li> ui-sref-active <li ui-sref-active="active"> <a ui-sref="about">About</a> </li> 包含模块 angular.module('uiRouter', ['ui.router']); 方便获得当前状态的方法 (绑到根作用域) app.run(['$rootScope', '$state', '$stateParams', function($rootScope, $state, $stateParams) { $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; } ]); 路由重定向 ($urlRouterProvider) app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) { $urlRouterProvider .when('/c?id', '/contacts/:id') .when('/user/:id', '/contacts/:id') .otherwise('/'); } ]); 状态配置 $stateProvider. state('about', { url: '/about', template: '<h1>Welcome to UI-Router Demo</h1>', // 使用 templateProvider 处理异步加载 templateProvider: ['$timeout', function($timeout) { return $timeout(function() { return '<p class="lead">UI-Router Resource</p>' + '<p>The second line</p>'; }, 100); } ], templateUrl: 'about.html', controller: 'UIRouterCtrl', controller: ['$scope', '$state', 'contacts', 'utils', function ($scope, $state, contacts, utils) { $scope.contacts = contacts; $scope.goToRandom = function () { var randId = utils.newRandomKey($scope.contacts, 'id', $state.params.contactId); $state.go('contacts.details', { contactId: randId }); } } ] }); 嵌套路由 (Nested Router) 父级路由 (Parent Router) $stateProvider. state('contacts', { abstract: true, url: '/contacts', templateUrl: 'contacts.html', // 处理异步数据调用 resolve: { contacts: ['contacts', function(contacts) { return contacts.all(); } ] }, controller: ['$scope', '$state', 'contacts', 'utils', function ($scope, $state, contacts, utils) { $scope.contacts = contacts; $scope.goToRandom = function () { var randId = utils.newRandomKey($scope.contacts, 'id', $state.params.contactId); $state.go('contacts.details', { contactId: randId }); } } ] }); 子级路由 (Children Router) $stateProvider .state('contacts.list', { url: '', templateUrl: 'contacts.list.html' }) .state('contacts.detail', { url: '/{contactId:[0-9]{1,4}}', views: { // 默认 view '': { templateUrl: 'contacts.detail.html', controller: ['$scope', '$stateParams', 'utils', function ($scope, $stateParams, utils) { $scope.contact = utils.findById($scope.contacts, $stateParams.contactId); } ] }, // 其他 view 'hint@': { template: 'This is contacts.detail populating the "hint" ui-view' }, 'menuTip': { templateProvider: ['$stateParams', function($stateParams) { return '<hr><small class="muted">Contact ID: ' + $stateParams.contactId + '</small>'; } ] } } }); HTML 代码 <h2>All Contacts</h2> <ul> <li ng-repeat="contact in contacts"> <a ui-sref="contacts.detail({contactId:contact.id})">{{contact.name}}</a> </li> </ul>
2016年06月21日
1
2