I'm new to angular, trying to bind an an element's content into the controller's Scope to be able to use it within another function:
here is the scenario am working around:
I want the content of the <span> element {{y.facetName}} in
<span ng-model="columnFacetname">{{y.facetName}}</span>
to be sent to the controller an be put in the object $scope.columnFacetname in the controller
Here is a snippet of what I'm working on:
<div ng-repeat="y in x.facetArr|limitTo: limit track by $index ">
<div class="list_items panel-body ">
<button class="ButtonforAccordion" ng-click="ListClicktnColumnFilterfunc(); onServerSideButtonItemsRequested(ListClicktnColumnFilter, myOrderBy)">
<span>{{$index+1}}</span>
<span ng-model="columnFacetname">{{y.facetName}}</span>
<span>{{y.facetValue}}</span>
</button>
</div>
</div>
angular.module('mainModule').controller('MainCtrl', function($scope, $http) {
$scope.columnFacetname = "";
$scope.ListClicktnColumnFilter = "";
$scope.ListClicktnColumnFilterfunc = function() {
$scope.ListClicktnColumnFilter = "\":\'" + $scope.columnFacetname + "\'";
};
}
the problem is that the $scope.ListClicktnColumnFilter doesn't show the $scope.columnFacetname within it, meaning that the $scope.columnFacetname is not well-binded.
In your ng-click instead of calling two different function
ng-click="ListClicktnColumnFilterfunc(); onServerSideButtonItemsRequested(ListClicktnColumnFilter, myOrderBy)"
you can declare like this
ng-click="columnFacetname = y.facetName; onServerSideButtonItemsRequested(columnFacetname , myOrderBy)"
You are trying to pass that model to another function by assigning it to ListClicktnColumnFilter in your controller
By doing in this way, you can achieve the same thing.
I have done one plunker with sample array,
http://embed.plnkr.co/YIwRLWXEOeK8NmYmT6VK/preview
Hope this helps!
Related
I am using JQUERY in my angularjs project since in some special conditions(AMP).
<div data-ng-repeat = "comment in blog.comments">
<i class="icon-edit font20 edit-faq-icon pointer" id="edit-comment" data-ng-click="editComment(comment);"></i>
</div>
Previously I had ng-click and now I can only find event by jquery.
$('#edit-comment').click(function(){
alert('hi');
})
But I want to access the parameter passed(comment) in the function editComment(comment).
Write a scope function in your angular controller like the below function. You will get the comment as parameter.
$scope.editComment=function(comment)
{
$scope.comment=comment;
};
Set an html content like this.
<div ng-model="comment" id="Comment"></div>
Now you can use
$('#Comment').val() to get the value in click
you can use .text() method to get the value of div.
also you can refer the following link http://api.jquery.com/text/
You can get the comment by passing the comment as a parameter to ng-click function.
var app = angular.module("myApp", []);
app.controller("myCntrlr",function($scope){
$scope.blog=
{
name:"Naresh",
comments:["test comment 1","test comment 2","test comment 3"]
}
$scope.editComment = function(comm){
alert(comm);
};
});
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js'></script>
<div ng-app="myApp" ng-controller="myCntrlr">
<div ng-repeat = "comment in blog.comments">
<button ng-click="editComment(comment);">get Comment</button>
</div>
</div>
I have an array of objects displayed with ng-repeat:
<div class = "row" ng-repeat="article in academicArticles">
<div class = "col-md-9 academicArticle" ng-click = "index = $index">
<a ui-sref ="article">
<h2> {{article.title}} </h2>
<p> {{academicArticles.indexOf(article)}} </p>
<img src = "{{article.img}}" class = "img-responsive">
</a>
</div>
</div>
I want to display the selected "article" in another state. Right now I have:
<div class ="container">
<div class = "jumbotron">
<img src = "../../../photos/danielpark.jpg">
<h1>{{academicArticles[index].title}}</h1>
<p> Written By: {{academicArticles[index].author}} </p>
</div>
</div>
No errors but {{academicArticles[index].author}} and {{academicArticles[index].title} are blank. How can I access the data of the selected article in another sate?
you can do that by passing the index of the selected "article" as state parameter to the other state.
assume the other state called state2, you need to add the state parameter to the state in the router registration, for example, if you rigstered the new state like this, you can add the index as follow
$stateProvider.state("state2", {
url: '/state2/:index',
templateUrl:'state2.html',
controller: 'state2Controller'});
and then in state2Controller you can access the index parameter using stateParams service like this :
(function() {
angular
.module("app")
.controller("state2Controller", state2Controller);
state2Controller.$inject = ["$scope", "$stateParams"];
function state2Controller($scope, $stateParams){
$scope.index = $stateParams.index;
}
})()
I think you are trapped by ng-repeat scope issue, the trick is not bind primitive types to scope directly instead use some object like $scope.model and $scope.model.authorId
I've been teaching myself how to use the as statement of Angularjs's controller, but struggling to make controllers communicate with others, using the as syntax.
<script type="text/javascript">
angular.module('angularApp', [])
.factory('MessageService', function(){
var message = {
addedItem: "initialMessge"
};
return {
returnMessage: message//This is supposed to be the "var message" defined above
};
})
.controller('DiaplayingProductController', function(MessageService){
var instance = this;
this.data = {
message: MessageService.returnMessage.addedItem
};
})
.controller('ProductController', function($scope, $http, MessageService) {
var instance = this;
this.data = {
message: MessageService.message,
//There are other stuff here
};
this.addItem = function(productName) {
$http({
//other tasks
}).then(function addSucces(response) {
instance.data.message.addedItem = productName;
});
};
});
<span ng-controller="DiaplayingProductController as dpc" ng-bind="dpc.data.message"></span>
<div ng-controller="ProductController as pc">
#foreach ($products as $index => $product)
<div class="product">
<button ng-click="pc.addItem({{$product->name}})>
Add it to Cart
</button>
</div>
#endforeach
</div>
I use Laravel, so {{$product->name}} and #foreach are Laravel's expression.
In a nutshell,
There are one <span> and multiple <button>s, based on the result of #foreach (Again, I use Laravel, so this is basically the same thing as php's foreach)
When one of the <button> is pressed, the content of <span> is supposed to be updated.
The event is triggered in ProductController, which is supposed to update message of DiaplayingProductController, via MessageService.
The message is not going to be sent to the span tag.
This question may be silly. However, there are not many information resources out there which deal with this as statements, so I'd like to ask some advice here. Thank you in advance!
What's this #foreach?
There's a coma in your attributes. Shouldn't be there.
The expression in your ng-click has a missing parenthesis. Also, it should be an expression, therefore the {{}} have nothing to do here.
The data object are not shared between the controllers. You should:
use directives and pass the data using attributes ('=').
set the data in the $scope, which is not as good a solution
use a service as an intermediary (each controller can set/get the value
from that service)
I've got some projects displayed in divs via ng-repeat.
Each div contains a link with the id of the project.
Basically I want to bind my project id on ng-click in order to update a factory. This will allow me to share the clicked project's id with another controller who will load the project details data only.
Here is my projects view:
<div ng-repeat="detail in projects.details">
<a ng-href="#!/project/project-details" ng-click="setId(detail.project_id)"><span></span></a>
</div>
Here is my factory:
app.factory('getGoodIdProjectDetails', function (){
var savedId = 1; //Default à 1
return {
getId : function () {
return savedId;
},
setId:function(idGet){
savedId = idGet;
return savedId;
}
}
});
Here are my controllers:
function ProjectCtrl($scope, $http, $timeout, getGoodIdProjectDetails) {
$scope.setId = function (idGet) {
$scope.idProjectDetails = getGoodIdProjectDetails.setId(idGet);
};
}
function ProjectDetailsCtrl($scope, $http, $timeout, getGoodIdProjectDetails) {
$scope.idProjectDetails = getGoodIdProjectDetails.getId();
}
In my view the console is displaying an error like I can't bind ng-click this way, but when I inspect the view it's sorting me the good thing, like ng-click="setId(8)"
I want the factory to update with the good id on click. Then I want to access this id in projectDetailsCtrl in order to load the project.
|| EDIT || : I changed the ng-click, that works fine, everything's good. Thx all
try this:
<div ng-repeat="detail in projects.details">
<a ng-href="#!/project/project-details" ng-click="setId(detail.project_id)"><span>Voir le projet ></span></a>
</div>
you don't need to use binding expression {{}} to pass values to functions
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 ... **/
});