Not sure if this is possible, but I have some content with an ng-if that I want to test by updating a property on one of the controller's variables within the console.
<div class="manager-only" ng-if="teamSchedule.userObject.isManager">
<a href="#add-game">
<input class="btn btn-success" type="button" value="Add New Game" />
</a>
</div>
As you can probably surmise, the userObject has an isManager property that is a boolean. On page load, it's initially set to false. I'm trying to update this within the console to test the ng-if.
I found that I could add window.teamSchedule = teamSchedule; to the controller in order to have a reference to it and its variables within the console, and this does allow me to change the object properties of the userObject, it appears. However the ng-if does not seem to respond to the change.
I've tried changing the ng-if to an ng-show and that didn't seem to work either. Anyone have a way to make this work or know if it's not possible?
Thanks!
First explanation why it doesn't work.
You change the Object out of the AngularJs scope, so Angular doesn't realize that you changed something.
If you don't use production mode on your development system, you can use this to access the scope.
angular.element($0).scope()
$0 is the last element selected in the chrome element inspector.
Try to access your object this way, if this does not trigger the changes, try to use
scope.$apply(function() { your modification })
Related
I'm confused from angular transclude scope. I'm trying to make let say collapsible directive. But binding inside the transclude scope will not change model of parent unless I use some object for the model eg. data.
<div>
data.prop: {{data.prop}} <br>
prop: {{prop}}
<collapsible>
data.prop: <input type="text" ng-model="data.prop" /> <br> // WILL CHANGE PARENT
prop: <input type="text" ng-model="prop" /> // WONT CHANGE PARENT
</collapsible>
</div>
I already read this topic and still I don't get it why I must use prefix to the model.
Confused about Angularjs transcluded and isolate scopes & bindings
Working example at http://plnkr.co/edit/z3IvR1a37jdNRCJWG0Yq?p=preview
In my app I'm using object for forms, so it works fine but I just want to know why is that.
When you use an object to bind to the model, your object is passed to the different scope as an reference, not a copy, in Javascript objects are passed to functions as a reference. In that case it will still reference to previous scope.
So I have a button called "show more" that will increase the number of items in a list once it reaches the maximum number of list I want to change to a button called "show less" which brings the list back to its default value.
I use an ng-if to determine which button to be shown and ng-click to determine the action. When using them together the ng-click stops working and nothing happens when I click.
here is the html I have written in jade, feedLimit is the number of items showing in the list.
button.btn.btn-primary.btn-block.btn-sm.btn-outline(type='button')(ng-if= "feedLimit < notifications.all.length", ng-click="feedLimit = feedLimit + 4")
span(translate) Show More
button.btn.btn-primary.btn-block.btn-sm.btn-outline(type='button')(ng-if= "feedLimit >= notifications.all.length", ng-click="feedLimit = 4")
span(translate) Show Less
I've tried using ng-show and ng-hide and they work fine but it is better to use ng-if, there is no animation and it is faster.
Here is the show more button's html output
<button type="button" ng-if="feedLimit < notifications.all.length" ng-click="feedLimit = feedLimit + 4" class="btn btn-primary btn-block btn-sm btn-outline ng-scope" style=""><span class="ng-scope">Show More</span></button>
I think your running into a common issue with angularjs and child scope inheritance.
You are data-binding to a primitive value and ng-if is creating a child scope. When your ng-click directive changes the value of 'feedLimit', you are actually creating a new 'feedLimit' property on the child scope but the ng-if directive is bound to the 'feedLimit' of the parent scope.
The solution is to avoid binding to a primitive value. Instead make sure you use dot-notation by binding to an object.
Instead of
<button ng-if="feedLimit < notifications.all.length" ng-click="feedLimit = feedLimit + 4">
try something like
<button ng-if="someObj.feedLimit < notifications.all.length" ng-click="someObj.feedLimit = someObj.feedLimit + 4">
Here is a more detailed explanation of whats going on.
https://github.com/angular/angular.js/wiki/Understanding-Scopes
Scope inheritance is normally straightforward, and you often don't
even need to know it is happening... until you try 2-way data binding
(i.e., form elements, ng-model) to a primitive (e.g., number, string,
boolean) defined on the parent scope from inside the child scope. It
doesn't work the way most people expect it should work. What happens
is that the child scope gets its own property that hides/shadows the
parent property of the same name. This is not something AngularJS is
doing – this is how JavaScript prototypal inheritance works. New
AngularJS developers often do not realize that ng-repeat, ng-switch,
ng-view and ng-include all create new child scopes, so the problem
often shows up when these directives are involved. (See this example
for a quick illustration of the problem.)
This issue with primitives can be easily avoided by following the
"best practice" of always have a '.' in your ng-models
I have an input like this :
<input ng-model="mysearch.myfield" id="myid"/>
that is bound to a filter
<table><tr ng-repeat="row in list|filter:mysearch">...</tr></table>
If I modify the input value in the GUI, it works perfectly, but if I try to modify its value via javascript/jquery
$("#myid").val("newvalue")
The input value is updated but the mysearch.myfield is not modified
Actually, I have a list that appears on user actions (it does not exist on page load):
<li onclick="changeTheInputValue('newvalue1')">newvalue1</li>
<li onclick="changeTheInputValue('newvalue2')">newvalue2</li>
...
with
function changeTheInputValue(v) {
$("#myid").val(v);
}
And it does not work when I click on an "li" (the input value is updated, ut the mysearch.myfield is not modified)
I also tried
<li ng-click="mysearch.myfield = 'newvalue1'">newvalue1</li>
<li ng-click="mysearch.myfield = 'newvalue2'">newvalue2</li>
...
but it does not work :(
Any idea ?
Thanks,
any javascript executing outside the angulars event loop won't be efective in angular untill you apply it. in order to do that you need to get the relevant scope and $apply the changes, since is not clear, how and why you are modifying the value outside the angular scope there is nothing much i can say except you could do something like
function changeTheInputValue(v) {
$("#myid").val(v);
angular.element($("#myid")).scope().$apply();
}
that should let angular know about the changes, how ever this is a bad design if using angular. there are far better ways to accomplish this same thing w/o having mixed execution scopes. (angular/the rest);
You are modifying the value of the input "#myid" using direct DOM manipulation. AngularJS is not aware of this. If you want both the html and the value of mysearch.myfield to update correctly, you must do so by modifying the mysearch.myfield property directly, either in a controller or via an ng-model binding or something similar.
The main reason this isn't working for you has to do with how AngularJS modifies the DOM. When you use jQuery to modify the DOM, you are circumventing angular. Angular has no way of knowing if you have changed something in the DOM except if you do it directly through Angular itself. In particular, if you are curious, read about the $compile and $digest services.
Hope this helps shed some light on the subject!
I am building a rather complex directive in which I need access to ng-model on a specific element in the template which is enclosed into ng-if directive... I have a plunker and the explanation on how to see the issue is below.
In the .compile function of the directive I have a line of code that looks like this
ngModel = elm.find('textarea').controller('ngModel');
console.log(ngModel);
In my template, I have a something like this:
<div ng-if="views.view">
<textarea ng-model="exp.val"></textarea>
</div>
When I use ng-show my console.log gets an object of ng-model, no problem ...
The requirement is very strict however and I have to use ng-if. When I use ng-if my console log gets undefined
The actual working version of the problem exists in this plunker
If you change the line 6 in template.html into ng-if you can see the behavior.
How do I have to write this line to retrieve the model when inclosed in ng-if.
ngModel = elm.find('textarea').controller('ngModel');
I also tried using attach-if directive by Simon Sparks. This directive is pretty cool, it preserves the scope unlike ng-if so if you specifically need to not render HTML but you need to preserve scope it works great.
I still have the same problem with invoking ngModel as I am doing it but because of applying custom filters in the directive I have to update ng-model in this way.
I am this one step away from finishing this directive. Hoping someone can help.
I have a div as show below:
<div id="xyz" dojoAttachPoint="xyz" style="display: none;"> </div>
Now I want to show/ hide it. If I do it using dojo.byID it works. But if I do it using dojoAttachppoint it does not work properly. I don't get any errors but changes don't take place.
dojo.byId("xyz").style.display="none";
dojo.byId("xyz").style.display="";
this.xyz.style.display ="none";
this.xyz.style.display ="";
What can be the problem?
Are you using the above in a template within a class declared using dojo.declare with base class dijit._Templated?
Your understanding of attach points is flaky. When dijit._Templated parses the tenmplate, and when it sees a "dojoAttachPoint" attribute, it will create a property in the dijit object with the attach point's name. Therefore, "xyz" is a property in the dijit class object. The name is taken from the attribute called "dojoAttachPoint" when the template is being read. The dojoAttachPoint attribute is no longer used afterwards.
If "this" points to the dijit class you created, this.xyz will point to the DOM element (i.e. the div), never a widget. Therefore it does not have a "domNode" property. Trace the source code in dijit/_Templated.js line#191 to confirm.
Therefore, you need to do some console.log calls to confirm that this.xyz is returning the correct div. If it does, then you can try dojo.style(this.xyz, "display", "none") to see if you can hide it etc.
As to why this.xyz.style.display = "none" won't work, it may be a browser-specific thing, as it should do the same thing as dojo.style. You'll need to dig deeper to find out.