AngularJS对带有contentEditable的普通元素directive一个ng-model

[code lang=”js”]

‘use strict’;
angular
.module(‘app’)
.directive(‘contenteditable’, function() {
return {
restrict: ‘A’, // only activate on element attribute
require: ‘?^ngModel’, // get a hold of NgModelController
link: function(scope, element, attrs, ngModel) {
if (!ngModel) {
return;
} // do nothing if no ng-model
// Specify how UI should be updated(更新ui)
ngModel.$render = function() {
element.html(ngModel.$viewValue || ”);
};
// Listen for change events to enable binding(添加事件)
element.on(‘blur keyup change’, function() {
scope.$apply(readViewText);
});
// No need to initialize, AngularJS will initialize the text based on ng-model attribute
// Write data to the model
function readViewText() {
var html = element.html();
// When we clear the content editable the browser leaves a <br> behind
// If strip-br attribute is provided then we strip this out
if (attrs.stripBr && html === ‘<br>’) {
html = ”;
}
ngModel.$setViewValue(html);
}
}
};
});
[/code]
Well-Crafted Apps: How make a two-way binding to your contenteditable DIV or SPAN using AngularJS directives

angularJS controller之间的通信

1、event
这里可以有两种方式,一种是$scope.$emit,然后通过监听$rootScope的事件获取参数;另一种是$rootScope.$broadcast,通过监听$scope的事件获取参数。
这两种方法在最新版本的Angular中已经没有性能区别了,主要就是事件发送的方向不同,可以按实际情况选择。
[code lang=”js”]
/******* example ****/
///////子级传递数据给父级
// 子级传递
$scope.$emit(‘transferType’, "我要发送给父");

// 父级接收
$scope.$on(‘transferType’, function(event, data) {
$scope.transferType = data;
//console.log(data),接收到的值
};

/////// 父级传递数据给子级
// 父级传递
$scope.transferType = ”;
$scope.$broadcast(‘transferType’, "我要发送给子");

// 子级接收
$scope.transferType = ”;
$scope.$on(‘transferType’, function(event, data) {
$scope.transferType = data;
//console.log(data),接收到的值
}
[/code]

2、service
可以创建一个专用的事件Service,也可以按照业务逻辑切分,将数据存储在相应的Service中。

3、$rootScope
这个方法可能会比较dirty一点,胜在方便,也就是把数据存在$rootScope中,这样各个子$scope都可以调用,不过需要注意一下生命周期

4、直接使用$scope.$$nextSibling及类似的属性
类似的还有$scope.$parent。这个方法的缺点就更多了,官方不推荐使用任何$$开头的属性,既增加了耦合,又需要处理异步的问题,而且scope的顺序也不是固定的。不推荐

另外就是通过本地存储、全局变量或者现代浏览器的postMessage来传递参数了,除非特殊情况,请避免这类方式。

AngularJS表单验证分析

文章转载自:http://www.oschina.net/translate/angularjs-form-validation

Angular 的表单属性 $valid, $invalid, $pristine, $dirty

Angular 提供了有关表单的属性来帮助我们验证表单. 他们给我们提供了各种有关一个表单及其输入的信息,并且应用到了表单和输入.
属性类
描述
$valid ng-valid Boolean 告诉我们这一项当前基于你设定的规则是否验证通过
$invalid ng-invalid Boolean 告诉我们这一项当前基于你设定的规则是否验证未通过
$pristine ng-pristine Boolean 如果表单或者输入框没有使用则为True
$dirty ng-dirty Boolean 如果表单或者输入框有使用到则为True
Angular 也提供了有关表单及其输入框的类,以便你能够依据每一个状态设置其样式.

访问表单属性

  • 访问表单属性: [code]<form name>.<angular property>[/code]
  • 访问一个输入框:[code]<form name>.<input name>.<angular property>[/code]

Angular 的验证规则

[code lang=”js”]
<input
ng-model="{ string }"
name="{ string }"
required //代表必填项
ng-required="{ boolean }"
ng-minlength="{ number }"
ng-maxlength="{ number }"
ng-pattern="{ string }"
ng-change="{ string }">
</input>
[/code]

实例验证代码

1、html表单代码

[code lang=”html”]
<!– pass in the variable if our form is valid or invalid –>
<form name="userForm" ng-submit="submitForm(userInfo,userForm)" novalidate> <!– novalidate prevents HTML5 validation since we will be validating ourselves –>

<!– NAME –>
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" ng-model="name" required>
</div>

<!– USERNAME –>
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control" ng-model="user.username" ng-minlength="3" ng-maxlength="8">
</div>

<!– EMAIL –>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="email">
</div>

<!– SUBMIT BUTTON –>
<!– 可以使用ng-disabled="formInfo.$invalid"(当输入不符合规则)来控制按钮的 点击状态
<button type="submit" class="btn btn-primary">Submit</button>
<!– 通过 表单已经使用担不符合规则,的逻辑产生布尔值来控制显示隐藏 –>
<span class="error" ng-show="formInfo.username.$invalid && !formInfo.username.$pristine">错误信息</span>
</form>
[/code]

2、js代码

[code lang=”js”]
// app.js
// create angular app
var validationApp = angular.module(‘validationApp’, []);

// create angular controller
validationApp.controller(‘mainController’, function($scope) {

// function to submit the form after all validation has occurred
$scope.submitForm = function(u,uf) {

// check to make sure the form is completely valid
if (uf.$valid) {
alert(‘our form is amazing’);
}

};

});
[/code]

功能实现

1、简单的控制提交按钮的状态

[code lang=”html”]
<!– 在from表单位置添加name和ng-submit,表单提交实际上就是提交到submitForm(userInfo,userForm),userInfo,userForm分别代表表单提交的数据和表单的状态 –>
<form class="form-horizontal" role="form" name="userForm" ng-submit="submitForm(userInfo,userForm)" novalidate>
<!– 在input位置添加规则(required代表必填项) –>
<input type="text" name="username" class="form-control" ng-model="user.username" ng-minlength="3" ng-maxlength="8" required>
<!– 在表单提交通过ng-disabled来实现状态控制 –>
<button type="submit" class="btn btn-success" ng-disabled="userForm.$invalid">登录</button>
[/code]

2、只在提交表单后显示错误信息

实现过程:
1.你要去掉提交按钮上的ng-disabled,因为我们想要用户即使是在表单没有全部验证完的情况下也能点击提交.
2.你要在表单已经被提交之后添加一个变量. 在你的 submitForm() 函数中, 只要加入 $scope.submitted = true 就行了;. 一旦表单被提交,它就会保存提交值为true的submitted变量.
3.将错误规则从ng-class=”{ ‘has-error’ : userForm.name.$invalid && !userForm.name.$pristine }” 调整为 ng-class=”{ ‘has-error’ : userForm.name.$invalid && !userForm.name.$pristine && submitted }”. 这就确保了错误消息只会在表单被提交时被显示出来. 你也许会需要为这个变量调整所有其它的 ng-class 和 ng-show.
[code lang=”html”]
<!– 在from表单位置添加name和ng-submit,表单提交实际上就是提交到submitForm(userInfo,userForm),userInfo,userForm分别代表表单提交的数据和表单的状态 –>
<form class="form-horizontal" role="form" name="userForm" ng-submit="submitForm(userInfo,userForm)" novalidate>
<!– 在input容器添加规则ng-class规则,同时修改错误显示的规则 –>
<div class="form-group " ng-class="{ ‘has-error’: userForm.email.$invalid && userForm.email.$dirty && submitted}">

<p class="help-block" ng-show="userForm.email.$invalid && userForm.email.$dirty && submitted">必须大于5个字符</p>
<!– 在input位置添加规则 –>
<input type="text" name="username" class="form-control" ng-model="user.username" ng-minlength="3" >
<!– 在表单提交去掉ng-disabled的状态控制 –>
<button type="submit" class="btn btn-success" >登录</button>
[/code]

遗留的问题

一个input有好几个规则,比如必须输入和最长字段,怎么来判断不同的错误??