我正在尝试创建一个就地编辑指令。我希望能够将它附加到任何类型的元素上,当用户将该元素悬停时,按下按钮时应显示一个编辑按钮,应显示一个文本字段,允许用户更改该字段的内容。
我在传回编辑后的值时遇到了一些麻烦。我怎样才能以某种方式将originalText
范围内saEditableController
属性的值绑定到saEditable
字段?
这是我的代码:
(function() {
'use strict';
var app = angular.module('saCommon.editable', []);
app.controller('saEditableController', ['$scope',
function($scope) {
$scope.text = angular.copy($scope.originalText);
$scope.submit = function() {
$scope.originalText = $scope.text;
console.log('In submit: ' + $scope.originalText);
};
}
]);
app.directive('saEditable', ['$rootScope', '$timeout', '$compile',
function($rootScope, $timeout, $compile) {
return {
restrict: 'A',
scope: {
'saEditable': '='
},
link: function($scope, $element, $attrs) {
var $formElement, $inputElement, scope;
var onBlur = function() {
$formElement.remove();
$element.show();
};
var onKeyPress = function(event) {
// Escape pressed
if (event.keyCode === 27) {
onBlur();
}
// Enter pressed
else if (event.keyCode === 13) {
//onBlur();
}
};
var onEdit = function() {
$formElement = $('<form ng-submit="submit()"></form>').
insertAfter($element).
attr('ng-controller', 'saEditableController');
$inputElement = $('<input type="text" ng-model="text"></input>').
appendTo($formElement).
on('blur', onBlur).
on('keypress', onKeyPress).
width($element.width()).
focus();
scope = $scope.$new();
scope.originalText = $scope.saEditable;
$timeout(function() {
$compile($formElement)(scope);
});
$element.hide();
return false;
};
var $editIcon = $('<a class="sa-editable-icon" href></a>').
hide().
on('click', onEdit).
appendTo($element);
$element.
css('position', 'relative').
mouseenter(function() {
$editIcon.show();
}).
mouseleave(function() {
$editIcon.hide();
});
}
};
}
]);
})();
该指令的使用方式如下:
<div sa-editable="collection.description">
{{ collection.description }}
</div>
谢谢!
答案 0 :(得分:1)
由于您在表单上使用ng-controller
,它将创建一个新的子范围,因此您必须建立一种在父范围和子范围之间进行通信的方法。
方法1:在范围内使用scope.$watch()
和模型的点符号。
示例Plunker: http://plnkr.co/edit/9MgWucf9JRuFe2A7qhlz?p=preview
不是将originalText
直接存储到范围中,而是使用如下对象包装它:
scope = $scope.$new();
scope.formModel = {
originalText: $scope.saEditable
};
然后您将能够观察到这些变化:
scope.$watch('formModel.originalText', function (value) {
$scope.saEditable = value;
});
方法2:使用$emit
和$on
即通过事件进行通信。
示例Plunker: http://plnkr.co/edit/4CrcUPy8fk9xrauKLPbx?p=preview
您可以使用$on
订阅此类'valueUpdated'
事件:
scope = $scope.$new();
scope.originalText = $scope.saEditable;
scope.$on('valueUpdated', function (e, value) {
e.stopPropagation();
$scope.saEditable = value;
});
然后$emit
来自表单控制器的事件:
$scope.submit = function() {
$scope.originalText = $scope.text;
console.log('In submit: ' + $scope.originalText);
$scope.$emit('valueUpdated', $scope.originalText);
};