问题
I have the following code: JSBin:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<body>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.Name = "John";
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input type="text" ng-model="Name"><br>
<br>
<textarea id="myText" ng-model="Name"></textarea>
</div>
<span id="fromQuery">to override</span>
<script>
$("#myText").on("change keyup paste", function() {
console.log("changed");
var x = document.querySelector('#myText');
console.log(x.textContent);
document.querySelector('#fromQuery').innerHTML = x.innerText
});
</script>
</body>
</html>
I want to realise two things:
1) the change to input should impact textarea and vice-versa, this has been already realised by AngularJS.
2) the change to textarea (either due to the change of input or from manual modifications) should impact the span. It does not work at the moment, the property textContent or innerText or innerHTML does not work.
Does anyone know what's wrong here?
Additionally, will it be a better practice to integrate the onchange event into myApp as well?
回答1:
The best practice is never use JQuery or angular.element() for DOM manipulation inside controllers. Controllers are only used for our business logic. We can use service, factory, $scope, value, constants etc inside it.
Bad Way -
We can do it with JQuery - but please don't do this.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<body>
<script>
var name = '';
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.Name = "John";
name = $scope.Name;
$scope.$watch('Name', function(newVal, oldVal){
name = newVal;
console.log(name);
});
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input id="name" type="text" ng-model="Name"><br>
<br>
<textarea id="myText" ng-model="Name"></textarea>
</div>
<span id="fromQuery">to overrided</span>
<script>
$("#myText, #name").on("keyup", function() {
console.log("changed");
document.querySelector('#fromQuery').innerHTML = name;
});
</script>
</body>
</html>
Good Way -
Here all things in myCtrl controller-
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<body>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.Name = "John";
$scope.overrideName = 'to override';
$scope.getName = function(){
$scope.overrideName = $scope.Name;
}
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input type="text" ng-model="Name" ng-keyup="getName()"><br>
<br>
<textarea id="myText" ng-model="Name" ng-keyup="getName()"></textarea>
<span id="fromQuery" >{{overrideName}}</span>
</div>
</body>
</html>
回答2:
It is working,:-
document.querySelector('#fromQuery').innerHTML = x.value;
回答3:
If you want the change in text-area to reflect in span do a watch on the text-area model. Before that , include the span tag inside your controller scope and assign a model variable to it like below:
Html :
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input type="text" ng-model="Name"><br>
<br>
<textarea id="myText" ng-model="Name"></textarea>
<span id="fromQuery" ng-model="spanValue">to override</span>
</div>
Controller :
$scope.$watch("Name", function () {
$scope.spanValue = $scope.Name;
});
来源:https://stackoverflow.com/questions/41001796/make-span-reactive-to-a-textarea-of-an-angularjs-app