I am following an online example. However, it doesn't work quite the way I had hoped it would. Now, I could easily do this with jQuery and a class, but I am trying to do it the "Angular Way".
The Angular Template for my tags is initially displaying. Once the scope starts to process, then it hides & the tags come-in as expected when binding.
Q: How do I prevent the Angular Template form initially displaying?
UPDATE:
Applying "ng-bind" only changes the nature of the problem. It doesn't solve the problem.
MY MARKUP LOOKS LIKE:
<div ng-controller="BlogsIndexController">
<div class="tags-cloud tags-cloud-category" ng-show="isShown">
<div class="tag" ng-repeat="category in categories">
{{category.Name}}
</div>
</div>
</div>
MY CONTROLLER LOOKS LIKE:
// CONTROLLER
application.controller('BlogsIndexController', function ($scope, $http, categoryTagsDataService) {
var vm = this;
// Internal
vm.on = {
databind: {
categories: function () {
var categories = categoryTagsDataService.list()
categories.success(function (data) {
$scope.categories = data;
$scope.isShown = true;
});
}
}
};
vm.databind = function () {
vm.on.databind.categories();
};
// Scope
$scope.isShown = false;
$scope.categories = [];
// Initialize
vm.databind();
});
You should use ngBind="category.Name" instead of {{category.Name}}:
<a href="#" data-iso-sort="iso-sort-category-{{category.SortKey}}"
ng-bind="category.Name"></a>
It is preferable to use ngBind instead of {{ expression }} if a template is momentarily displayed by the browser in its raw state before Angular compiles it. Since ngBind is an element attribute, it makes the bindings invisible to the user while the page is loading.
More info here.
Update 1:
I've never used ngCloak, but docs say that it may help you:
<a href="#" data-iso-sort="iso-sort-category-{{category.SortKey}}"
ng-bind="category.Name" ng-cloak></a>
Update 2:
I've checked this answer and it seems that you need also to add the next CSS rule:
/*
Allow angular.js to be loaded in body, hiding cloaked elements until
templates compile. The !important is important given that there may be
other selectors that are more specific or come later and might alter display.
*/
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none !important;
}
Related
I parsed three different json files here's my code
//factory
app.factory('myapp', ['$http',
function($http) {
function getLists() {
var tab = ['url1', 'url2', 'url3'];
var list = [];
for(i=0; i<tab.length; i++){
$http.get(tab[i])
.then(function(res) {
list.push(res.data);
});
}
return list;
} return {
getLists: getLists
};
]);
//controller
$scope.list = myapp.getLists();
My challenge now is to display this data in the html file once all the data is loaded so the whole table appear without displaying the page if one of the json files is not loaded yet.
<tr ng-repeat="d in list">
<td>{{d.nm}}</td>
<td>{{d.cty}}</td>
<td>{{d.hse}}</td>
<td>{{d.yrs}}</td>
</tr>
I tried the ng-clock but in vain I am using AngularJs 1.3.5
You could add a default class to everything you want to be hidden like this
body.is-loading { display: none; }
(or add a spinner/loading indicator, which is probably better as the user gets the information, what's going on)
As soon as you're data is loaded and inserted, i.e. after list.push(res.data);, you remove this class. Either via dom manipulation angular.element(body).removeClass('is-loading') or by simply setting a $scope/$rootScope variable, which adds/removes this class using ng-class:
<body ng-class='{"is-loading": isLoading }'>
I also have the same problem with my page, the solution I found is to asynchronously bootstrap my angular application. follow this link which help me out.
https://blog.mariusschulz.com/2014/10/22/asynchronously-bootstrapping-angularjs-applications-with-server-side-data
Hope this will work out for you as well...
In the below code,
<label>
<input type="checkbox" ng-model="showList">
Show unordered list
</label>
<ng-include src="getList()"></ng-include>
$scope.getList() gets invoked on change of $scope.showList by check or uncheck, where $scope.showList is used as,
app3.controller('gListCtrl', function($scope){
$scope.getList = function(){
return $scope.showList ? "ulgrocerylist.html" : "grocerylist.html";
};
});
Why $scope.getList() gets invoked on change of state of $scope.showList?
Similar code,
<p>
<button ng-disabled="disableButton">Button</button>
</p>
<p>
<input type="checkbox"
ng-model="disableButton">DisableButton
</p>
make sense to me, because disableButton state is changing, so button gets disabled or enabled due to two way binding.
First of all, You're a little bit incorrect on your question. The $scope.getList() function gets invoked not only on a state change, but on every digest cycle. Let me explain.
Because the framework has absolutelly no clue what code is in the getList function. It does not statically analize your code, since it would be both very hard and very inneficient. Due to the nature of how you can use AngularJS, you could be changing the output of getList according to a variable in a completely different controller, service, scope, etc. Thus, this output might need to be rerendered upon every digest cycle. AngularJS recognizes this, because you have the function call in your template and calls it on every digest to check whether it needs to swap out the template.
Consider this application structure:
<div ng-app="testTest">
<script type="text/ng-template" id="template.html">
<div>Hello world!</div>
</script>
<div ng-controller="templateViewer">
<div>
<div ng-include="content()"></div>
</div>
</div>
<div ng-controller="templateChanger">
<button ng-click="handleClick()">Show / hide content</button>
</div>
</div>
and this code to wire it:
var app = angular.module('testTest', []);
app.factory('template', function() {
return {
show: false
};
});
app.controller('templateChanger', function($scope, template) {
$scope.handleClick = function() {
// toggle showing of template
template.show = !template.show;
};
});
app.controller('templateViewer', function($scope, template) {
// if the result of this function is not re-evaluated on every digest cycle,
// Angular has no idea whether to show or hide the template.
$scope.content = function() {
return template.show ? 'template.html' : '';
};
});
So, the framework needs to rely on this constant re-evaluation of properties and functions that are binded to the templates in the HTML. Since all the data structures that you use are plain javascript objects, and you don't explicitly tell the framework that something in your viewmodel has changed (as you would do by invoking set() methods on your models in other frameworks, such as Backbone or Ember) – angular has to check all variables and re-run all the functions that could possibly change the look of your view, and ng-include is one of these cases.
You can use watcher or observe events on showList variable value changes.
I want to find a way to do clean communication between my two sibling directives. I want to implement "insertAtCaret" functionality for a textarea in one directive, to be called from another.
<text-holder ng-model='model.text' />
<text-inserter>
<a ng-click='insert("hello")'>Hello</a>
</text-inserter>
text-holder turns into something like this:
<div class='my-class'>
<h3>Enter some text:</h3>
<textarea ng-model='ngModel'></textarea>
</div>
The text-inserter needs to insert stuff into that textarea - what's the cleanest angular-ish way to allow that communication? I want to be able to support multiple instances of that on the page. Should I just create a unique id for each one from a shared service? It seems a little unclean.
You can :
Wrappe your directive in outer DOM element.
create a communication directive on this element.
Use the controller of this directive as an API for communication between the two directives.
Use require from the two directive, to, set, the text.
<div text-com-directive>
<text-holder ng-model='model.text' />
<text-inserter>
<a ng-click='insert("hello")'>Hello</a>
</text-inserter>
</div>
Directive :
directive('textComDirective', function(){
return {
scope:{},
controller: function($scope){
// create functions that will be used to set/use the text inserter.
}
}
});
The only chain between two directives is a variable that is supposed to be updated, this is also used by both directive. The text-inserter directive is sort of like choosing the method to be executed to the text-holder
html
<text-holder ng-model='model.text'></text-holder>
<text-inserter>
<a ng-click='model.insert("hello")'>Hello</a>
</text-inserter>
script.js
var app = angular.module('testapp',[]);
app.controller('appController', function ($scope) {
$scope.model = {text: 'sample', insert: function(a){$scope.model.text = a}};
})
app.directive('textInserter', function () {
return {
restrict: 'E',
trasclude: true // important to keep the content that is defined outside of directive
}
});
Sample
The insert function is set in the controller that is holding the variable to pass to the directive, this way helps us to easy understand what logic should be applied and is going to happen for the model variable in the initiated scope it self.
The more benefit is you can situational change the behavior for some specific instance.
Please I wanna know how to change the inside the dynamically in angularjs.
I'm using the NGresource and pulling json data from the back-end and i want to change it dynamically then i go to a new article for example.
You can change the HTML title and head elements on a per-view basis by using angularjs-viewhead.
here how to use it.
put the angularjs-viewhead.js in your asset folder
Declare as a dependency of your application as normal
var app = angular.module('myApp', ['ng', 'viewhead']);
This sort of setup can be achieved in an AngularJS application using the view-title directive. First, set up your title element to bind to the special scope variable viewTitle, which will be set when a tilted view is instantiated:
</title ng-bind-template="{{viewTitle}} - FooBaz">FooBaz</title>
With this in place, add to each view's template a single view-title element setting the view's title:
<view-title>About</view-title>
Like so:
document.title = 'Text';
Changing your title in JS is tricky when dealing with search engines as you may get curly braces in search results or the title for the page won't be right. However, if you have a rendering server for Google/Bing/Yahoo!, then it'll show up right when crawled. That, however, is another issue entirely. In order to do this, move your ng-app directive to the html attribute:
<html ng-app="myApp">
<head>
<title ng-bind="titleService.currentTitle">My Default Title</title>
</head>
<body>
<ng-view></ng-view>
</body>
</html>
Then create a service and bind it to the root scope:
angular.module('myApp')
.service('TitleService', function($location) {
var DEFAULT_TITLE = 'My Default Title';
return {
setTitle: function(title) {
this.currentTitle = title || DEFAULT_TITLE;
}
};
});
angular.module('myApp').run(function(TitleService, $rootScope) {
// This is mainly for a separation of concerns. These lines could
// easily go in the service definition.
$rootScope.$on('$locationChangeSuccess', TitleService.setTitle);
$rootScope.titleService = TitleService;
});
This assures that the default title will always be set by default. However, if you would like to set the title on a per-controller/directive basis you can do this inside of your code:
angular.module('myApp')
.controller('MainCtrl', function($scope, $location, TitleService, Article) {
// I'm just guessing what your logic might look like
var id = $location.search().articleId;
Article.get(id).then(function(article){
// Set the title however you want with article data
TitleService.setTitle(article.title);
});
});
EDIT: I moved a line to the run function to separate the concerns of the service from the concerns of the application.
Try this:
document.title.innerHTML = "" //Text Goes in Quotes.
Good luck!
i want to get the text of div using angularjs . I have this code
<div ng-click="update()" id="myform.value">Here </div>
where as my controller is something like this
var myapp= angular.module("myapp",[]);
myapp.controller("HelloController",function($scope,$http){
$scope.myform ={};
function update()
{
// If i have a textbox i can get its value from below alert
alert($scope.myform.value);
}
});
Can anyone also recommand me any good link for angularjs . I dont find angularjs reference as a learning source .
You should send the click event in the function, your html code should be :
<div ng-click="update($event)" id="myform.value">Here </div>
And your update function should have the event parameter which you'll get the div element from and then get the text from the element like this :
function update(event)
{
alert(event.target.innerHTML);
}
i just thought i put together a proper answer for everybody looking into this question later.
Whenever you do have the desire to change dom elements in angular you need to make a step back and think once more what exactly you want to achieve. Chances are you are doing something wring (unless you are in a link function there you should handle exactly that).
So where is the value comming, it should not come from the dom itself, it should be within your controller and brought into the dom with a ng-bind or {{ }} expression like:
<div>{{ likeText }}</div>
In the controller now you can change the text as needed by doing:
$scope.likeText = 'Like';
$scope.update = function() {
$scope.likeText = 'dislike';
}
For angular tutorials there is a good resource here -> http://angular.codeschool.com/
Redefine your function as
$scope.update = function() {
alert($scope.myform.value);
}
A better way to do it would be to use ng-model
https://docs.angularjs.org/api/ng/directive/ngModel
Check the example, these docs can be a bit wordy