Angular零散知识点收集

收集一些平时使用Angularjs1.x及Angular Material碰到的问题的解决方法.

Angular get方法传参

$http get parameters does not work

道在AngularJS中使用POST方法提交传递参数是:

1
$http.post('/api/users/add', { user:user })

如果是GET方法的话则是:

1
2
3
$http.get('/api/users/add', {
params: { user:user }
})


获取url参数而不刷新页面

How can I set a query parameter in AngularJS without doing a route?

当设置了URL发生改变时,默认会刷新页面,如果只是想添加查询数据到url而无需刷新页面,可以通过$routeProvider的属性reloadOnSearch来设置

1
2
3
4
5
$routeProvider.when('/daylist', {
templateUrl: 'partials/daylist',
controller: 'DayListCtrl',
reloadOnSearch: false
})

Controller中就可以使用$location.search()方法来获取url中的参数,或者设置query参数

1
2
3
http://localhost:3000/daylist
$location.search('id',123) =>
http://localhost:3000/daylist?id=123


使用$locationChangeStart替换$routeChangeStart

AngularJs - cancel route change event

在之前我们使用$routeChangeStart来触发路由变化之后的操作,如今需要使用$locationChangeStart来代替,详见https://github.com/angular/angular.js/issues/2109

1
2
3
4
$scope.$on('$locationChangeStart', function(event, next, current){
$scope.isSignIn = AuthService.isAuthenticated();
//...
});


处理解析换行符变<br />

angularjs处理/n转
时候
不会解析的问题

angular中的ng-bind-html指令和$sce服务

使用angularjs时,如果注入的数据中包含了部分特殊字符时,如\n要转成html标签<br>的话,可以使用ng-bind-html标签配合$sce服务来解决。

1
<p ng-bind-html="test"></p>

然后在js代码中使用$scetrustAsHtml方法:

1
2
3
4
app.controller('TestController', ['$scope', '$sce', function($scope,$sce) {
//将test中的字符串里的换行符转为标签
$scope.test=$sce.trustAsHtml(str.replace(/\n/g,"<br/>"));
}]);


ui-router子页面如何获取父级页面的url参数

学习 ui-router 系列文章索引
Angular ui-router - how to access parameters in nested, named view, passed from the parent template?

ui-router中如果有子页面嵌套在父级页面,如果需要获取到父级页面传入的路由参数,例如/users/1/blogs/1,首先需要在全局配置:

1
2
3
4
5
6
7
8
9
10
11
$stateProvider
.state('user',{
url: '/users/:userId',
templateUrl: '/static/partials/user.html',
controller: 'userCtrl'
})
.state('user.blog',{
url: '/users/:userId/blogs/:blogId',
templateUrl: '/static/partials/blog.html',
controller: 'userBlogCtrl'
})

然后在html中可以这样调用:

1
<a ui-sref="user.blog({ userId: blog.author.id, page:1 })">

接下来在控制类中通过注入的$stateParams获取对应的属性:

1
2
3
4
5
6
app.controller('userBlogCtrl',
['$scope', '$stateParams', '$state',
function($scope, $stateParams, $state){
console.log($stateParams.userId);
console.log($stateParams.blogId);
}]);


Angular Material更改日期选择组件默认格式

Change format of md-datepicker in Angular Material

Angular Material中的日期选择组件$mdDateLocaleProvider选中的日期格式为dd/MM/yyyy,如果想要替换成其他格式(比如yyyy-MM-dd),可以使用formatDate方法:

1
2
3
4
5
6
7
8
9
10
11
myApp.config(['$mdDateLocaleProvider', function($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
if (date instanceof Date && !isNaN(date.valueOf())) {
var y = date.getFullYear().toString();
var m = (date.getMonth()+1).toString();
var d = date.getDate().toString();
return y + '-' + (m[1]?m:"0"+m) + '-' + (d[1]?d:"0"+d);
}
return '';
};
}]);


Angular Material对话框传值

Passing data to mdDialog

$mdDialog中有个属性是locals,通过它可以给对应的控制器传入参数:

1
2
3
4
5
6
7
8
9
10
11
12
$mdDialog.show({
templateUrl: 'showImg.html',
locals: { imgUrl: url },
controller: function($scope, $mdDialog, imgUrl){
$scope.imgUrl = imgUrl;
$scope.cancel = function(){
$mdDialog.cancel();
};
},
clickOutsideToClose:true,
targetEvent: ev
});

传入的参数必须以对象形式传入,必须从控制器中注入


Angularjs与Requirejs集成

使用 RequireJS 加载 AngularJS
Angular — Using RequireJs (AMD)
angularjs集成requirejs

首先在页面中引入requirejs

1
<script src="/static/bower_components/requirejs/require.js" data-main="/static/js/main"></script>

这样requirejs会自动加载main.js,接下来就是配置入口文件main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
require.config({
//配置库路径
paths: {
'angular': '/static/bower_components/angular/angular',
'angular-ui-bootstrap': '/static/bower_components/angular-bootstrap/ui-bootstrap-tpls',
'angular-ui-router': '/static/bower_components/angular-ui-router/release/angular-ui-router'
//...
},
//导出全局变量
shim: {
'angular': {
exports: 'angular'
},
'angular-ui-bootstrap': {
deps: ['angular'],
exports: 'angular-ui-bootstrap'
},
'angular-ui-router': {
deps: ['angular'],
exports: 'angular-ui-router'
}
//...
}
});

//初始化创建ngApp
require(['angular', 'app', 'router', 'controller', 'service', 'directive'], function(angular) {
angular.bootstrap(document, ['app']);
});

接下来是遵循AMD规范的app.js

1
2
3
4
5
define('app', ['angular', 'angular-ui-bootstrap', 'angular-ui-router'], 
function(angular){
'use strict';
return angular.module('app', ['ui.bootstrap', 'ui.router']);
});

这样,其他的模块就可以使用app了。
接下来是路由管理工具router.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
define(['app'], function(app){
return app.run(['$rootScope', '$location', '$state', '$stateParams',
function($rootScope, $location, $state, $stateParams, AuthService, Restangular){
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
if (toState.data.requireLogin) {
$location.path('/');
};
});
}])
.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home',{
url: '/',
templateUrl: '/static/partials/home.html',
data: { requireLogin: false }
});
});
});

controller.js中也可以使用app这个根模块了:

1
2
3
4
5
6
7
8
define(['app'], function(app) {
'use strict';
app.controller('appCtrl',
['$scope', '$location', '$http',
function($scope, $location, $http){
//...
}
});

其余service.js,directive.js也类似。