ngChange doesn't work when the model is changed programmatically? - javascript

It says in the docs that ngChange will not fire: "if the model is changed programmatically and not by a change to the input value".
Does this mean that if you ever change the model programmatically, you can't use ngChange?
Or does it mean that you can't use ngChange if:
1) You change the model programmatically
AND
2) You're unable to change the model via the input field

It just means that the ngChange expression won't be evaluated if javascript is used to change the model. If you wanted ngChange to fire you would need to programmatically call the expression similar to the following:
<input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
You would need to manually call the change function if you wanted it to fire:
$scope.confirmed = 'test';
$scope.change();

If I read and understand this correctly, unfortunatelly you can't do it with ng-change as you say, but I'm not 100% sure.
I was thinking about ng-model-options, a new feature that came with AngularJS 1.3 and maybe this can push you forward.
There is an automatical options for getters and setters that allows you to change the model in real time. Theoretically, you could use this and call your update function with ng-bind.
Maybe this can be your possible solution to solve your problem...
(function(angular) {
'use strict';
angular.module('getterSetterExample', [])
.controller('ExampleController', ['$scope', function($scope) {
var _name = 'Brian';
$scope.user = {
name: function(newName) {
return angular.isDefined(newName) ? (_name = newName) : _name;
}
};
}]);
})(window.angular);
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-ngModelOptions-directive-getter-setter-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.7/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="getterSetterExample">
<div ng-controller="ExampleController">
<form name="userForm">
Name:
<input type="text" name="userName"
ng-model="user.name"
ng-model-options="{ getterSetter: true }" />
</form>
<pre>user.name = <span ng-bind="user.name()"></span></pre>
</div>
</body>
</html>

Related

Strict ng-model value in Angularjs

How to assign strict value to ng-model, so that "" not equal to false. and radio got deseleted when names equals ""
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = ''
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<input type="radio" ng-model="names" ng-value="false" >select only when model is false not ""
</div>
</body>
</html>
Not sure what exact behavior you are looking for but, you could put a function in ng-checked that takes names as an argument to implement the behavior you want.
input tag
ng-checked="myValue(names)"
controller
$scope.myValue = function(names) {
if (names === '') {
...
}
}

Angular.js output value live on ng-click

I'm new to angular and little bit confused with it. So basically I created a simple button and i want to run function foo() whitch assigns variable var one = 1; to $scope and outputs it in <p>{{one}}<p> every time its clicked like in live typing but this seems not working. Please provide me a solution to this.
<html ng-app="app">
<!-- Body tag augmented with ngController directive -->
<body ng-controller="myController">
<input type="text" ng-model="name">
<p>{{name}}</p>
<p>{{one}}</p>
<button ng-click="foo()">1</button>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="controller.js"></script>
</body>
</html>
controller:
var app = angular.module('app',[]);
app.controller('myController', ['$scope',function($scope){
var one = 1;
$scope.name = name;
function foo(){
return $scope.one = one;
}
}]);
function foo() dont exist in $scope your controller "myController"
if you declaration:
$scope.foo = function(){}
in your controller, then this work for you
when you are calling controller function from the html, controller function should be scope. Other wise ng-click directive doesn't recognize the function.
same concept goes to binding variable to html. only scope variables can directly bind to html using curly brackets. so inside foo function var one should assign to scope.one in order to display it in the html.
angular.module("app",[])
.controller("ctrl",function($scope){
var one = 1;
$scope.name = name;
$scope.foo = function(){
$scope.one = one;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<input type="text" ng-model="name">
<p>{{name}}</p>
<p>{{one}}</p>
<button ng-click="foo()">1</button>
</div>

Why will always use anonymous function in AngularJS

I see almost tutorial use anonymous function in AngularJS, instead of normal function, like function name(para1) {}. Please see this link: http://www.w3schools.com/angular/tryit.asp?filename=try_ng_controller_property
I change to normal function, but it cannot work, Please advise. Thanks.
<div ng-app="myApp" ng-controller="personCtrl as main">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{main.fullName()}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('personCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
function fullName() {
return $scope.firstName + " " + $scope.lastName;
};
});
</script>
The idea of $scope is to have an object where all fields and functions are defined on, so that you are able to reference the fields and functions from your template.
When you don't attach the function to $scope it will not be visible for angular to be called. So the contract is that in your controller function, you add everything you need to the $scope object passed by the framework and by doing so, you can later access the fields or call the functions from your template. Everything you reference in directives like ng-model or put into {{ }} will be evaluated by angular, but angular doesn't know what you mean with the expression fullName() as written in your snippet link or fails finding it in the controller when written as main.fullName().
For details on the concept of $scope have a look at the angular docs on scopes.
What you can do (and it is also a good practice) is to declare your function and then (maybe in tha init of the controlelr) assign them to the $scope ..so is more clear when you'll re read it something like:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="personCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{fullName()}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('personCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.fullName = fullName; //<-- here you assign it
function fullName() {
return $scope.firstName + " " + $scope.lastName;
};
});
</script>
</body>
</html>

how to check value entered in input field is already available or not in angularjs

I would like to know in the below example how can i check whether entered value in input field is already available or not.
I have an input field, on key press i want to check the input field value with the values from names array and display error message down if value is already present in names array and also disable the button. If value entered is not present in the names array i dont want to display error message and enable the Add button. Here is the plunkr - https://plnkr.co/edit/rz0tjxhEajz7848Ws3ig?p=preview
html -
<!DOCTYPE html>
<html>
<head>
<script src="angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body ng-app="test" ng-controller="testController">
Name: <input type="text"/>
<button on-keypress="submit()">Add</button>
</body>
</html>
script -
var testController = angular.module('test', []);
testController.controller('testController', ['$scope', function($scope) {
$scope.names = ["name1","name2","name3"];
angular.forEach($scope.names, function(x) {
console.log(x);
});
}]);
Instead of looping through the array each time , use ng-change and check for duplicate using array.prototype.includes().
Updated Plunkr
Html:
<body ng-app="test" ng-controller="testController">
Name: <input type="text" ng-change="checkName()" ng-model="name"/>
<button ng-keypress="submit()">Add</button>
<p ng-show="showError">Name already exists</p>
</body>
Controller:
$scope.names = ["name1","name2","name3"];
$scope.showError = false;
$scope.checkName = function (){
if($scope.names.includes($scope.name)){
$scope.showError = true;
} else {
$scope.showError = false;
}
}
<body ng-app="test" ng-controller="testController">
Name: <input type="text" id="getValue"/>
<button on-keypress="submit()">Add</button>
</body>
Added id above to retrieve value from text field
$scope.names = ["name1","name2","name3"];
for (i = 0; i < $scope.names.length; i++) {
if (document.getElementById('getValue').value === $scope.names[i]) {
alert('something');
return;
};
};
Then ran a function to check for names in array and if there alert and stop function.
To hide add class to <button on-keypress="submit()" class="random">Add</button> and call from controller $('.random').hide();, note it's JQuery being used here.

Why is the binding not working for $scope in controller?

I'm new to Angular.
I am having problems dealing with variables back and forth between my controller and html.
In my controller not only I want to read $scope, but I also want to use it in a function I have in my services.
This is my factory:
angular.module('myApp.services', [])
.factory('hotels', function($http){
return{
search: function(city, callback){
$http({
method: 'GET',
url: 'http://myhotels.com/hotels/?city='+city+
cache: true
}).success(callback);
}
};
})
controller:
angular.module('myApp.controllers', [])
.controller('SearchHotelsController', ['$scope', 'hotels', function($scope, hotels){
$scope.hotelCity = "";
hotels.search($scope.hotelCity, function(hotelResults){
$scope.hotelResults = hotelResults;
});
}])
and in the html I don't have a button to call the function. It is supposed to be called when I get the scope variable (hotelResults):
<input class="form-control" type="text" ng-model="hotelCity">
<a ng-href="#/searchResults"><button>Search</button></a>
and when it routes to that page, which uses the same controller, I get:
{{hotelResults.name}}
================================================================
I also tried declaring $scope.hotels = {hotelCity: "sf"}; in th controller , then put this in html: <input type="text" ng-model="hotels.hotelCity"> and in my controller to call $scope.hotels.hotelCity in the function, but still they are not connected! no matter what the user puts in the input, I get 'sf' for my hotelCity.
Please someone shed a light on this for me, thanks!
I am also new-bie to angular, and looking at your question, i am not fully aware what you are actually looking for but what i have understood and came up with this. Might help.
<html ng-app="myApp">
<head><title>Test</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
</head>
<body>
<div class="test-wrap" ng-controller="myHotels">
<input type="text" name="h" ng-model="hotelcity" />
<button ng- click="search()">Search</button>
<p>List of Hotel's</p>
<ul>
<li ng-repeat="h in hotel | filter:hotelcity">{{h.name}}</li>
</ul>
</div>
</body>
</html>
<script type="text/javascript">
var myApp = angular.module('myApp',[]);
myApp.controller('myHotels', ['$scope', function($scope) {
$scope.hotel = [{"name":"Test1 hotel"},{"name":"Test2 hotel"},{"name":"Test3 hotel"}];
$scope.search = function(){
console.log($scope.hotelcity);
}
}]);
</script>
I finally decided to pass my data through my url and then get it with $routeParams in my controller.
I didn't figure out the problem with my code, and I kind of expected Angular to be this smooth with passing variables back and forth, but I guess this particular situation is a javascript issue with different scopes and function arguments.
I also learned about the Closure concept of javascript which didn't help me either!
Solution: I put a button at the bottom of the page inside an tag;
<a ng-href="#/searchResults/{{hotelCity}}"><button>Search</button></a>
then in routeProvide in my app.js file:
$routeProvider.when('/searchResults/:city', {templateUrl: 'partials/second.html', controller: 'secondController'});
then in controller:
hotels.search($routeParams.city, function(hotelResults){
$scope.hotelResults = hotelResults;
});
[make sure to declare $routeParams in your controller next to $scope]

Categories

Resources