When I use the JS to append a p tag into a div,the ng-click not working.My code as follows:
$("#newsArList").append("<p ng-click=\"myNavigator.pushPage(\'article.html\', { animation : \'slide\' } )\">Go To Article</p>");`
Actually,I
console.log("<p ng-click=\"myNavigator.pushPage(\'./www/article.html\', { animation : \'slide\' } )\">1234</p>");`the result is `<p ng-click="myNavigator.pushPage('article.html', { animation : 'slide' } )">1234</p>
I just copy this one into the <div id="newsArList"></div>,and it working.
I don't know the reason for this situation. Any suggestions?
You use angular directive, so you must compile the code into the DOM:
$("#newsArList").append('<p ng-click="myNavigator.pushPage(\'article.html\', { animation : \'slide\' } )">Go To Article</p>');
ons.compile($("#newsArList")[0]);
As described here:
ons.compile function converts your custom elements based HTML to a
normal DOM structure. Most browsers does not (yet) support custom
elements by default, you need to call the function every time to make
the magic happen.
Related
I'm reviewing old classes and I try to finish the exercices I couldn't do before. This class is in Ionic1, using Angular1.
I have a directive using two parameters; the first one is an object which data are to be displayed, and the second one is a parameter to hide/show some elements in the display
Here is the view implementing the controller :
<ion-list>
<film-directive
ng-repeat="tmpMovie in myController.movieList"
movie="tmpMovie"
displayBtnAddFav="false"
></film-directive>
</ion-list>
And here is the directive construction :
const FilmDir = function(){
return {
"restrict":"E",
"scope":{
"movie" :"=",
"displayBtnAddFav" :"&"
},
"template":`
<ion-item>
<p ng-if="displayBtnAddFav">DISPLAY WHEN TRUE</p>
<p ng-if="!displayBtnAddFav">DISPLAY WHEN FALSE</p>
</ion-item>`,
"controller":function($scope){
//TODO
}
}
};
All the files are correctly referenced. My directive is displayed in the view, but the "displayBtnAddFav" value isn't interpreted correctly. The "DISPLAY WHEN TRUE" is always displayed
I tried :
calling the directive with displayBtnAddFav="false"
calling the directive with displayBtnAddFav=false
replacing the boolean value by a string ("a" or "b") and using ng-if="displayBtnAddFav==='a'"
Nothing works as intended and I seem to be out of options. Would any of you see what I'm doing wrong?
So I think the issue here is the scope binding:
Per the angular documentation: & bindings are ideal for binding callback functions to directive behaviors. (https://docs.angularjs.org/guide/directive)
Different bindings are ideal for different scenarios. Try changing it from a & to an =. This should allow for angular to interpret the boolean your trying to pass correctly.
const FilmDir = function(){
return {
"restrict":"E",
"scope":{
"movie" :"=",
"displayBtnAddFav" :"="
},
"template":`
<ion-item>
<p ng-if="displayBtnAddFav">DISPLAY WHEN TRUE</p>
<p ng-if="!displayBtnAddFav">DISPLAY WHEN FALSE</p>
</ion-item>`,
"controller":function($scope){
//TODO
}
}
};
Thanks a lot Kyle for your input.
After some more tests, it appears you're right despite what the doc was telling me.
Another crucial point I realized it that the directive doesn't like "camelCase" arguments : I had to change the displayBtnAddFav to displaybtnaddfav for it to work properly.
There is a lot of information on how to use ng-class and ng-style on elements. But I was wondering if there is a way to use angular to change the "settings" of a class.
So for example, say that you had a css class that looked as follows:
.testclass {
color: red;
background-color: blue;
}
I want to use angular to change the color:red to color:black, without attaching angular to the HTML DOM object, but via the class instead.
OK, this isn't a very useful example. What I was really planning to use it for was to hide part of ck-editor (class cle_top) and I want to set the whole class to hidden when someone clicks a button (and visible if the click it again).
======== To make it clearer, this is the bit of HTML I want to hide =======
<span id="cke_1_top" class="cke_top cke_reset_all" role="presentation" style="height: auto; -webkit-user-select: none;"><span id="cke_8" class="cke_voice_label">
Editor toolbars</span><span id="cke_1_toolbox" class="cke_toolbox" role="group" aria-labelledby="cke_8" onmousedown="return false;">
<span id="cke_11" class="cke_toolbar" aria-labelledby="cke_11_label" role="toolbar"><span id="cke_11_label" class="cke_voice_label">
But I need to do it without being able to add angular hooks in the HTML code (like adding ng-class to the span, which would have been a simple solution)
Attached is a JSfiddle that shows my problem, and as you can see, the toolbar button does nothing.
http://jsfiddle.net/vrghost/uqvo3ceh/
Which kind of works now, it adds the class invisible to the span, however, it does not hide the span that it is looking at.
Use the same process on a test text and it works...
Don't know of anything that will edit the class itself, but that probably isn't want you want to do. Other options are:
1) Create a second class, that comes after the first one in your CSS file that adds / changes the properties you want. Ex:
.testclass {
color: red;
background-color: blue;
}
.newclass {
color: green; // change property in first CSS class
display: none; // or hide
}
Then apply the second class conditionally:
<div class="text-class" ng-class="{newclass: hideScopeFlag}">blah</div>
2) Simply use ng-if, ng-hide, or ng-show if all you are doing is hiding something. Ex:
<div class="text-class" ng-hide="hideScopeFlag">blah</div>
or
<div class="text-class" ng-show="!hideScopeFlag">blah</div>
Why not simply toggle the class off/on for that element when the user clicks the button? (Edit: You said you want to "set the whole class to hidden" - I am assuming you mean to remove the class?)
To answer your question though, you can do this with JavaScript using document.styleSheets.
See this Stack Overflow question and the blog post it references. It mentions that there may be some browser compatibility issues. I have not investigated this.
EDIT: This implementation of 'ng-toggle' will allow you to hide or show an element with a single button.
The simplest solution without messing with the stylesheets is to add a new rule like
.visibleOff .testclass {
color: black;
}
and then you just need to toggle the "visibleOff" class on a parent element (the wrapper or the body element) of the editor.
To hide certain elements in the DOM you can also use a $scope variable that acts as a boolean. You can set it to false by default and on button click toggle it to true and back.
$scope.hidden = false;
$scope.toggleHide = function(){
$scope.hidden = !$scope.hidden;
}
In your dom you can then wrap your element with an ng-hide="hidden" attribute like so:
<div ng-hide="hidden">...</div>
<button ng-click="toggleHide()">togglehide</button>
A plunker example can be found here: http://plnkr.co/edit/?p=preview
If anyone wanted to know how to do this, potentially this could be useful for other things as well.
Created a function that uses document.querySelector to find the element, then just do a toggle to turn on or of, and that, as they say, is it folks.
$scope.toolBarVisible = function(){
console.log("Changing visibility");
var element = document.querySelector( '.cke_top' );
console.log("Just to do some debugging we check " + element);
var myEl = angular.element( element );
myEl.toggle();
element = document.querySelector( '.cke_bottom' );
myEl = angular.element( element );
myEl.toggle();
var myEl2 = angular.element( document.querySelector( '.test' ) );
myEl2.toggleClass("invisible")
}
And for those that are looking closely, yes, it hides the bottom as well, and all without changing ckeditor or the code.
Hope someone finds it helpful.
As far as I know angular doesn't link hidden HTML elements, so I assume when the viewport width is 500px or larger, the first paragraph is not linked (the mydirective link function is not triggered).
<p mydirective>{{content | customFilter}}<p>
<p mydirective>{{content}}<p>
p {
display:block;
}
#screen and min-width:500px {
p:nth-child(1) {
display:none;
}
}
However, the filtering function is still triggered as well as binding function for mydirective. Is there any way to prevent angular from triggering filter function and binding function for hidden HTML elements?
The task here for me is to show filtered data for small screens (less than 500px) and unfiltered data for larger screens.
Instead of using CSS to hide and show elements, use ng-if which will then remove the elements from the DOM and therefore prevent any Angular related magic happening for those elements (Until you want them back again).
I have a HTML-Document containing moustache expressions that angular-dart evaluates very well:
</head>
<body ng-cloak>
<ctrlTextElements>
<div id="stage">outside: {{ctrlTextElements.test1('three')}}</div>
</ctrlTextElements>
I want to dynamicaly add some HTML with moustache expression like so:
CtrlTextElements.addTextElement(mousePos.x, mousePos.y);
var div = dom.querySelector('#stage');
HttpRequest.getString("../path/text.html").then((r) {
div.children.add(new Element.html(r, validator: new AllowAllValidator()));
});
The content of the added text.html looks like this:
<div>inside: (not evaluated): {{ctrlTextElements.test1('three')}}</div>
That's the result in the browser:
outside: three
inside: (not evaluated):{{ctrlTextElements.test1('three')}}
How can I reevaluate the moustache expressions inside content that has been applied after the page was loaded?
The problem is that you are mixing jQuery like logic with angular logic here : manipulating the dom 'by hand' is rarely a good solution.
The problem here is that your newly added binding has not been compiled by angularjs = it has not been indexed as a directive that should be watched for and updated when scope changes.
Either you try a more angular way, for example using ng-hide or ng-repeat directive to display your content according to the controllers $scope (or another custom directive), or you try to $compile your newly added directive ( but this is bad ) : https://docs.angularjs.org/api/ng/service/$compile .
Maybe try in your controller :
$scope.$compile( div );
Not sure of the syntax though. Maybe you would need to write
<span ng-bind="..."></span>
instead of
{{ ... }}
to make it work.
#Alexhv is right. Sorry for my previous answer. I assumed it is about Polymer. Was already time for bed.
You can find a code example in my answer to this question: setInnerHtml doesn't evaluate Mustache
The pub package bwu_angular (http://pub.dartlang.org/packages/bwu_angular) contains this code as a Decorator (Directive) named bwu-safe-html
I am new to using ng-animate with AngularJS 1.2. I am not sure why my ng-animate does not work a certain class name but works with the default for a simple fade in that I saw in an example.
In this example, I try to set my ng-animate class to be 'animation':
http://plnkr.co/edit/QWQUUVdcLmzLKRvVibqN?p=preview
but when I use the default, and my class name for animations is just ".ng-enter" and ".ng-leave", the fade in animation seems to work fine.
http://plnkr.co/edit/lEQhMwd6RWmsdmJbosu0?p=preview
Any help would be greatly appreciated, thanks!
The ng-animate attribute is deprecated in 1.2.
In 1.2 you define the appropriate CSS classes using a special naming convention. If you want a specific name like 'animation', you need to add that class to the element you want to animate.
As long as you have the correct CSS classes, some directives will be animated automatically. Which ones can be found here: http://docs.angularjs.org/api/ngAnimate
This is the reason your animation works in your second example when just defining the ".ng-enter" class. This would however automatically animate all directives that support the enter animation.
I have updated your first example to make it work with the class named 'animation':
HTML:
<li ng-repeat="item in items" class="animation">{{item}}</li>
CSS (Keeping selectors ungrouped for clarity):
.animation {
-webkit-transition: 1s;
}
.animation.ng-enter {
opacity: 0;
}
.animation.ng-leave {
opacity: 1;
}
.animation.ng-enter.ng-enter-active {
opacity: 1;
}
.animation.ng-leave.ng-leave-active {
opacity: 0;
}
Plunker: http://plnkr.co/edit/J0qJEMmwdzqXzu733fJf?p=preview
Also important to remember to add the animation module as a dependency to your module definition. Just in case anyone else is having problems getting animations working and hasn't done this.
angular.module('myApp', ['ngAnimate']);
You must check that the version of your angular.min.js matches with the version of angular-animate.min.js.
I got mine fixed this way.
As Tasse said ng-animate is deprecated, we need to use the class.
If you are copying CSS from angularjs web site http://www.nganimate.org/angularjs/ng-repeat/move then you need to modify those CSS in a particular format
For complete detail check Apply Angularjs Animation in 2 minutes
This is in addition to accepted answer, for those who are trying to animate an element with ng-show directive. These are styles which must be used:
.animation.ng-hide-remove {
transition:2s linear all;
opacity:0;
}
.animation.ng-hide-remove.ng-hide-remove-active {
opacity:1;
}
Please note, not all angular directives adds ng-enter, ng-enter-active, ng-leave and ng-leave-active. For example, ng-show directive adds ng-hide-remove at the beginning of animation and ng-hide-remove-active at the end of it. For more details follow this link:
https://www.w3schools.com/angular/angular_animations.asp