Sometimes we need to add ng-model to non-input type elements to achieve two-way data binding, thereby reducing redundant code, then you can try this method
For example: I use the contenteditable attribute in my page to implement div elements that can be directly compiled by users
html:
<style> .text{ margin:0 auto; width:100px; height:50px; border:1px solid red; } </style> </head> <body> <div ng-controller="selectController"> <div ng-repeat="pop in citylist"> <div class="text" contenteditable="true" ng-model="pop.pop"></div> </div> <button ng-click="cs()">输出新数据</button> </div> </body>
But if you bind ng-model directly, you will definitely not get the data. In this case, you need to add custom attributes to it, as shown below.
js:
<script> var app = angular.module('app', []); app.controller('selectController', function ($scope) { $scope.citylist=[{id:1,pop:"北京"},{id:1,pop:"上海"},{id:1,pop:"广州"}]; $scope.p={}; $scope.cs=function(){ console.log($scope.citylist); } }).directive('contenteditable', function() {//自定义ngModel的属性可以用在div等其他元素中 return { restrict: 'A', // 作为属性使用 require: '?ngModel', // 此指令所代替的函数 link: function(scope, element, attrs, ngModel) { if (!ngModel) { return; } // do nothing if no ng-model // Specify how UI should be updated 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); } } }; }) </script>
The parameter categories are as follows:
Explanation of some parameters
restrict:
(string) optional parameter, indicating how the instruction is declared in the DOM;
The values are: E (element), A (attribute), C (class), M (comment), where the default value is A;
E (element):
A (attribute):
2.require
The string represents the name of another command, which will be used as the fourth parameter of the link function
We can give an example to illustrate the specific usage
Suppose now we want to write two instructions. There are many overlapping methods in the link function of the two instructions (the link function will be discussed later),
At this time we can write these repeated methods in the controller of the third instruction (as mentioned above, controller is often used to provide reuse behavior between instructions)
Then among these two instructions, require the instruction with the controller field (the third instruction),
Finally, these overlapping methods can be referenced through the fourth parameter of the link function.
<!doctype html> <html ng-app="myApp"> <head> <script src="http://cdn.staticfile.org/angular.js/1.2.10/angular.min.js"></script> </head> <body> <outer-directive> <inner-directive></inner-directive> <inner-directive2></inner-directive2> </outer-directive> <script> var app = angular.module('myApp', []); app.directive('outerDirective', function() { return { scope: {}, restrict: 'AE', controller: function($scope) { this.say = function(someDirective) { console.log('Got:' + someDirective.message); }; } }; }); app.directive('innerDirective', function() { return { scope: {}, restrict: 'AE', require: '^outerDirective', link: function(scope, elem, attrs, controllerInstance) { scope.message = "Hi,leifeng"; controllerInstance.say(scope); } }; }); app.directive('innerDirective2', function() { return { scope: {}, restrict: 'AE', require: '^outerDirective', link: function(scope, elem, attrs, controllerInstance) { scope.message = "Hi,shushu"; controllerInstance.say(scope); } }; }); </script> </body> </html>
The instructions innerDirective and innerDirective2 in the above example reuse the method defined in the controller of the instruction outerDirective
also further explains that the controller in the instruction is used to communicate between different instructions.
In addition, we can add one of the following prefixes to the require parameter value, which will change the behavior of the search controller:
(1) Without prefix, the instruction will search in the controller provided by itself. If no controller is found, an error will be thrown
(2)? If the required controller is not found in the current instruction, null will be passed to the fourth parameter of the link connection function
(3)^If the required controller is not found in the current directive, the controller of the parent element will be searched
(4)?^ Combination