I have working to pass a value from Jquery to angular js. But I have found undefined in angular js.
My code :
HTML :
<button onclick="change('5')"></button>
<input type="hidden" ng-model="data" id="one" />
<button ng-click="test(data)">Test</button>
JQuery:
function change(data)
{
$("#one").val(data).change();
}
Angular Js :
$scope.test= function(data)
{
console.log(data)
}
But I got undefined. How can I do this ?
You can do it for sure*, however you should probably not, as this blend of jQuery and Angular will soon become hard to maintain. This is not really well-design.
Instead, use angular directives and methods, in your case it's straightforward:
<button ng-click="change('5')"></button>
<input type="hidden" ng-model="data" id="one" />
<button ng-click="test(data)">Test</button>
and in Angular controller:
$scope.change = function(x) {
$scope.data = x;
};
* If you really want it: you need to let Angular know that you have changed the model from outside of digest cycle with manual $("#one").val(data).change(); angular.element($("#one")).scope().$apply();.
Related
I have a constant file which looks like this
demo.constant.js
// Add detail constans here
(function () {
angular.module('myApp').constant('TYPE', {
DYNAMIC: 'dynamic',
STATIC: 'static'
});
}());
Now I have a controller file that looks similar to this.
demo.controller.js
(function() {
var DemoController = function(DEP1,DEP2, .... , TYPE)
console.log(TYPE.DYNAMIC); // works perfectly
var self = this;
self.type = '';
...
...
angular.module('myApp.controllers').controller('DemoController', DemoController);
})();
I am trying to access these constants in the HTML file like this:-
<div ng-controller="DemoController as self">
<span ng-if="(self.type === 'dynamic')"> <!--instead of 'dynamic' I want to use TYPE.DYNAMIC-->
...
...
...
</span>
</div>
Note:- {{self.type}} works but {{TYPE.DYNAMIC}} doesn't.
Another problem is that I want to use this constant as the value of radio buttons.
somewhat like this:-
<input type="radio" name="type" ng-model="self.inputType" value="dynamic"> <!-- Here I want to use TYPE.DYNAMIC -->
<input type="radio" name="type" ng-model="self.inputType" value="static"> <!-- Same as above -->
I have searched everywhere but nothing seems to work. Please Help!!
One approach is to assign the constant to a controller property:
function DemoController(DEP1,DEP2, /*.... ,*/ TYPE) {
console.log(TYPE.DYNAMIC); // works perfectly
this.TYPE = TYPE;
}
angular.module('myApp.controllers').controller('DemoController', DemoController)
Then use it in the template:
<div ng-controller="DemoController as $ctrl">
<span ng-if="$ctrl.type === $ctrl.TYPE.DYNAMIC">
...
</span>
</div>
Note: The ng-if directive uses creates a child scope. Consider instead using the ng-show directive which uses CSS and less resources.
You can use $rootScope and initilize it in run phase:
angular.module('app')
.run(function ($rootScope, TYPE) {
$rootScope.TYPE = TYPE
});
then you can use it directly in your HTML
I am updating and modifying a project using Angular JS 1.2.25.
I have my controller where I have a value called vm.stageValue which is then called in template with an ng-if, so when the vm.stageValue increments it shows different containers. But whhen I define a value on the vm object that I want to interpolate on the template, eg a string that will be used and will not change on the template, I cannot seem to get it display.
This has makes me think I have not set up my controller correctly using the vm method.
It seems weird that I can use the ng-if and call function from the controller using ng-click on the template but I cannot interpolate a string or send it to another child component
Code is below, thank you in advance. Any help would be hugely appreciated
Controller
angular
.module('formModule')
.controller('NewBusinessFormCtrl', [
function() {
let vm = this;
// Methods used in controller
vm.methods = {
incrementStageValue: incrementStageValue,
decrementStageValue: decrementStageValue,
canIncrement: canIncrement,
canDecrement: canDecrement
};
//Initial stage values
vm.stageValue = 1;
vm.maxStageValue = 7;
// This is the string that I want to interpolate below
vm.contactFormCategory = 'New Business';
}
]);
Template of Controller
<div class="new_busines_cf" ng-controller="NewBusinessFormCtrl as vm">
<div class="form_wrapper">
<div ng-if="vm.stageValue == 1">
<input-text
class="form_input"
ng-model="ngModel"
input-text-label="This is the label">
</input-text>
// I want to send the vm.contactFormCategory into the component
// Value is sending but the component display 'vm.contactFormCategory'
// Not the value set in the controller
<form-headline
form-headline-sup-title="vm.contactFormCategory"
form-headline-text="This is a form headline text">
</form-headline>
</div>
// Trying to interpolate value here into template, but nothing display
{{vm.contactFormCategory}}
<div ng-if="vm.stageValue == 2">
<input-text
class="form_input"
ng-model="ngModel"
input-text-label="This is the label of stage 2">
</input-text>
<form-headline
form-headline-sup-title="vm.contactFormCategory"
form-headline-text="This is a form headline text">
</form-headline>
</div>
<button ng-click="vm.methods.incrementStageValue()">Increment Value</button>
<button ng-click="vm.methods.decrementStageValue()">decrement Value</button>
</div>
</div>
** Form Headline **
angular
.module('formModule')
.directive('formHeadline', function() {
return {
restrict: 'E',
templateUrl: '/partials/form/form-headline.component.html',
scope: {
formHeadlineText: '#',
formHeadlineSupTitle: '#'
},
link: function () {
}
};
});
Change your ng-if to
<div ng-if="vm.stageValue === '2'">
I have problem with following code. I can solve the issue with $scope, but this time request to do it without using $scope in controller. I am using "controller as" to control the view.
<body ng-app="appModule" >
<div ng-controller="calculatorController as calc">
<input type="number" name="firstDigit" placeholder="insert num" ng-model="calc.firstDigit">
<input type="number" name="secondDigit" placeholder="insert num" ng-model="calc.secondDigit">
<span>{{calc.result}}</span>
</div>
</body>
(function(){
angular
.module("calculatorModule")
.controller("calculatorController", calculatorController)
function calculatorController(){
var calc = this;
calc.result = calc.firstDigit + calc.secondDigit;
}
})();
Well, you have two options - you can do it with watchers, or with a function to get the result. I prefer the latter, but it's up to you. Here's an example of how you can get it to work:
Side note - learn the controller as syntax, it will save you thousands of headaches down the road with nested scoping and child-parent relationship issues with $scope -- here's a great article explaining controller as
(function () {
angular.module("calculatorModule", [])
.controller("calculatorController", [function() {
var calc = this;
calc.getResult = function() {
return calc.firstDigit + calc.secondDigit;
}
calc.result = calc.getResult();
}]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="calculatorModule" ng-controller="calculatorController as calc">
<input type="number" name="firstDigit" placeholder="insert num" ng-model="calc.firstDigit">
<input type="number" name="secondDigit" placeholder="insert num" ng-model="calc.secondDigit">
<span>{{calc.getResult()}}</span>
</div>
Your module definition is false!
Should be
module("calculatorModule", [])
I have a little demo on jsfiddle :
HTML:
<input type="checkbox" id="chkUsr{{usr.Id}}" ng-model="usr.Checked">
{{usr.Name}} : {{usr.Checked}}
<input type="text" ng-model="research"/>
<div ng-repeat="entity in entities | filter:research | log">
Hello {{entity.id}}!
JavaScript:
app.filter('log', function() {
return function(items) {
console.log('yo');
return items;
};
});
The log filter is called when input change (even the checkbox).
How to change that and trigger log filter only when text input change ?
That's because angular runs $digest and updates all the scope properties even if one variable in the scope changes. It is called "dirty checking".
Learn more about how angular works: http://www.sitepoint.com/understanding-angulars-apply-digest/
I'm developing a simple todo app with Angular and Firebase using AngularFire module.
So I have a boolean attribute in my model represented by a checkbox in the template, the problem is that I'm trying to use the three way data binding from AngularFire using the $bind method to keep the all changes syncronized (firebase data, DOM and ng-model) but the firebase data is not updating when I select a checkbox.
Here's my controller where I'm using the AngularFire $bind method:
angular.module('singularPracticeApp')
.controller('TodoCtrl', ['$scope', 'TodoService', function ($scope, todoService) {
$scope.todos = todoService;
$scope.todos.$bind($scope, 'todo.done');
$scope.addTodo = function () {
$scope.todos.$add({text: $scope.todoText, done:false});
$scope.todoText = '';
};
$scope.remaining = function () {
var count = -11;
angular.forEach($scope.todos, function(todo){
count += todo.done? 0 : 1;
});
return count;
};
$scope.clear = function (id) {
$scope.todos.$remove(id);
};
}]);
And here is the tempalte file:
<div ng-controller="TodoCtrl">
<h4>Task runner</h4>
<span>{{remaining()}} todos left.</span>
<ul>
<li ng-repeat="(id, todo) in todos">
<input type="checkbox" ng-model="todo.done">
<span ng-if="todo.done" style="color: #ddd;">{{todo.text}}</span>
<span ng-if="todo.done == false">{{todo.text}}</span>
<small ng-if="todo.done">clear</small>
</li>
</ul>
<form ng-submit="addTodo()">
<input type="text" ng-model="todoText" placeholder="New todo item">
<input type="submit" class="btn btn-primary" value="add">
</form>
</div>
Am I missing something? Is really possible to make this work with a simple checkbox?
Thanks in advance.
You haven't included todoService here so it's going to be difficult to give you an accurate answer. I'll assume that todoService returns a $firebase instance containing the todos since that seems likely. Keep in mind that the problem could be in that code as well.
Several problems you can address, which may resolve your issue:
Your TodoCtrl is not per-item
You seem to be using TodoCtrl as if it were created per-item in the ng-repeat. However, it exists outside the scope of ng-repeat and is only created once for the entire list.
Ng-repeat does not re-use your existing controller scope.
Directives operate in an isolate scope. That means that they do not share scope with your controller. So when you do ng-repeat="todo in todos" you do not add todo into your controller's scope.
This makes sense since each ng-repeat iteration would overwrite the same todo object.
You are trying to double-bind to a synchronized object
You are trying to create a three-way binding $scope.todos.[$todo].done, but you have already created a three-way binding on $scope.todos. Instead, let $scope.todos take care of synchronization.
You've attempted to bind $scope.todos to a property in itself
When you call $bind, you are binding $scope.todos to $scope.todos.todo.done. Obviously this self-referential statement isn't what you intended. I can't tell what is returned by your service but maybe you meant this:
todoService.$bind($scope, 'todos');
If you don't want to automatically push changes on the entire todos list, you can add a $save call instead of using $bind:
$scope.todos = todoService;
<input type="checkbox" ng-model="todo.done" ng-change="$parent.todos.$save(id)">
All together:
angular.module('singularPracticeApp')
.service('todoService', function($firebase) {
return $firebase( new Firebase(URL_TO_TODOS_LIST) );
});
.controller('TodoCtrl', function($scope, todoService) {
todoService.$bind($scope, 'todos');
$scope.addTodo = function () {
$scope.todos.$add({text: $scope.todoText, done:false});
$scope.todoText = '';
};
/** ... and so on ... **/
});