Does Angularjs provide any method that can traverse the DOM for text after a new view is returned? The filter seems to almost accomplish this but I'm not looking to return a new array of elements. For example;
html
<div ng-view="">
<ul>
<li>Milk</li>
<li>Eggs</li>
<li>Cheese</li>
</ul>
</div>
js
$(document).ready(function() {
var app = angular.module('app', ['ngRoute'])
.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/', { templateUrl: 'example.html' })
}]);
app.controller('rttController', function($scope, $location) {
$scope.$on('$locationChangeSuccess', function(event) {
// Search through the DOM for text returned in this view
});
});
My end goal is to have an array of predefined keywords that I'd be searching for in the DOM:
var foods[] = {"yogurt", "butter", "margarine"} .
Any ideas?
No it doesn't provide this functionality. Is it not possible to load the variables into an array and loop through that. The using ng-repeat you can display them on the page in your list.
Are you limited to having these items in HTML or would you be able to load them into an array and display them?
Maybe you could look into child scopes and having a controller within the HTML file you are including to manage the list?
Related
I am learning how to use ngRoute to split my html forms into separate views. When I add data to the main array in the index.html the array updates correctly, but when I try the same approach in the html forms that are added in through the ng-view, the array does not render correctly. I can debug and see that the array is getting the new name added, but it will not render on the html.
Index.html
<h1> Names </h1>
<ul ng-repeat="name in names">
<li>{{name.fname}}</li>
</ul>
<h1>Add name in index.html</h1>
<input type="text" ng-model="name" />
<button ng-click="addName(name)">add name</button>
<ul>
<li> First</li>
<li> Second</li>
</ul>
<div class="container">
<div ng-view></div>
</div>
Apps.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider) {
$routeProvider
.when('/first', {
templateUrl: 'pages/first.html',
controller: 'mainController'
})
.when('/second', {
templateUrl: 'pages/second.html',
controller: 'mainController'
})
});
myApp.controller('mainController', ['$scope', '$log', function($scope, $log) {
$scope.names = [{fname:'john',lname:'doe'},{fname:'jane',lname:'doe'}];
$scope.addName = function(name){
$scope.names.push({fname:name,lname:'no last name'});
}
}]);
first and second.html are identical
<h1>Add name in first.html</h1>
<input type="text" ng-model="name" />
<button ng-click="addName(name)">add name</button>
This is by design.
The $scope is limited to the scope of the controller, which is everything that is rendered inside the ng-view. This means there are two collections named names, one on the app scope, and one on the controller scope. When you modify the names collection inside the controller, it only modifies this collection, not the one referenced in the root level of the app. (I am assuming that you bind mainController to the body tag, otherwise the addName() in index.html wouldn't work. This by itself is not a great choice, you should not put another controller instance into itself, unless you absolutely know what you are doing.)
The proper way to handle this situation is to put the names collection and the addName() function into a service that you inject into your controllers.
Basically I want to achieve like this scenario:
https://i.stack.imgur.com/LLTcK.png
My research led me to $compile, $trustAsHtml,at last directive.
In $compile and $trustAsHtml I can only append static template or only html but can't use dynamic things such ui-sref, ng-click etc.
So, I tried to create directive it is not working and also I am unable to add multiple template on click.
controller :
app.controller('Ctrl', ['$rootScope', '$scope',function ($rootScope, $scope)
{
$rootScope.enableDirective=false;
if(userHasOneApp){// checking some at least one app then only do action
$rootScope.appicon="img_url"; // data which i am passing
$rootScope.appname="App_name"; // data which i am passing
$rootScope.enableDirective=true;
}
}]);
custom directive:
app.directive('headerTemplate', function () {
return {
template:'<a ui-sref="/event" ng-click="editIt()">'
+'<img src="{{appicon}}"></a>'
+'<span>{{appname}}</span>',
scope:{
appname:'=',
appicon:'='
}
};
});
Header view :
<div> class="headerdiv">
<ul ng-if="enableDirective">
<li header-template appicon="appicon">
</li>
</ul>
</div>
Main view :
<div> class="maindiv">
<ui-view></ui-view> <!--basically I want to append template here -->
<button>Add next template</button>
</div>
Where I am doing wrong ?
Well i was facing the same issue
Check out the following link
This will surely help you.
I have implemented this and it worked in my scenario where i wanted to serve a directive when required i.e Lazy Loading of directive
https://www.codeproject.com/Articles/838402/Lazy-loading-directives-in-AngularJS-the-easy-way
I have a LAMP website that i am trying to convert to be built on MEAN and I've split the index page into partials so i could have a SPA.
I am completely new to MEAN but i'm slowly learning and trying things however i'm now stuck on JQuery slider plugin that I am using in one of my partials and it does not load any images in the placeholder when the website is ran.
I know that i am supposed to use directives so that JQuery function is loaded after the partial page is loaded into the main page and hence why nothing is being displayed where the slider should be.
This is my partial page that contains the snippet of the slider for a single image (there are 3 of these 'li' blocks at the moment for 3 images):
home.html
<div id="pm-slider" class="pm-slider">
<ul class="pm-slides-container" id="pm_slides_container">
<li data-thumb="public/app/img/home/slide1a.jpg" class="pmslide_0"><img src="public/app/img/home/slide1.jpg" alt="img01" />
<div class="pm-holder">
<div class="pm-caption">
<h1>Medical professionals</h1>
<span class="pm-caption-decription">
that you can trust
</span>
learn more <i class="fa fa-plus"></i>
</div>
</div>
</li>
</ul>
</div>
My index.html file contains div ng-view tag where all of home.html should go.
app.js contains this code for routing and I know that here should go the .directives function for the JQuery plugin
var digiProm = angular.module('digiProm', [
'ngRoute']);
digiProm.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'public/app/partials/home.html'
})
.when('/services', {
templateUrl: 'public/app/partials/services.html'
})
.otherwise({
redirectTo: 'partials/home.html'
});
}]);
After watching multiple videos as well as tutorials i can't figure out how i should write my directive function to work.. I am trying to work out how to use this type of format
digiProm.directive('slider', ['$rootScope', function($rootScope) {
return {
restrict: 'EA',
templateUrl: '/path/to/template',
link: function(scope, iElement, attrs) {
//attrs references any attributes on the directive element in html
//iElement is the actual DOM element of the directive,
//so you can bind to it with jQuery
$(iElement).bxSlider({
mode: 'fade',
captions: true
});
}
};
}]);
Is the templateUrl here supposed to be the path to the jquery file for the slideshow?
What the heck would go inside the link: function(...) ?? This script has been shown as an example on how to use the bxSlider and i'm trying to use a Pulse PM-Slider so not sure what functions i'm supposed to call for it to load after the partial has been loaded...
Any kind of help is much appreciated.
Thank you in advance
If the directive is only activating on an element that already exists in another template then you don't need templateUrl.
That is used to be able to inject html into an element. in other words a directive can define it's own template
Also the restrict is to tell directive whether to look for E-an element , or A an attribute or C- a class.
I suggest you add an attribute since it makes it easier to see later on in the markup
<div slider id="pm-slider" class="pm-slider">
Then remove templateUrl from your directive declaration object.
Also note that when jQuery is included in page before angular.js iElement is already a jQuery object so you can just use iElement.bxslider({....})
I am beginner in angular js
HTML
<div ng-app="myapp">
<div ng-controller="maincontrol">
<div ng-show="!vis">show</div>
<div ng-show="vis">hide</div>
</div>
<div ng-view></div>
</div>
JS
var app = angular.module('myapp', ['ngRoute'])
app.controller('maincontrol', function ($scope) {
$scope.vis = true;
$scope.fun = function () {
if ($scope.user == "home" && $scope.pass == "home") {
console.log($scope.user, $scope.pass);
$scope.vis = false;
}
}
})
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html'
})
.when('/contact', {
templateUrl: 'contact.html'
})
});
and also i have two html pages like
home.html
<div ng-controller="maincontrol">
<input ng-model="user"/>
<input ng-model="pass"/>
<div ng-click="fun()">
click
</div>
</div>
contact.html
<div>
contact
</div>
my expectation is after entering home into user and pass. if i click 'click' i need to show 'show' label instead of 'hide'. pls help me.
Each controller has its own scope, when you wrote $scope.vis=false on fun(), you actually created a new variable on maincontroler1 scope. If you expected this variable to affect the view which is binded to maincontroler scope, it won't happen.
I suggest 2 options:
You can use one controller for entire app (If you use same controller in two tags it will still create a new scope although it is the same controller), this way the fun() method that was called from the first view will change the boolean in the single controller and will affect the second view. Please note when you use ng-view you will have to get the variable from the parent.
So I used this code:
$parent.user
$parent.pass
Create this working plunker for you.
Share the vis boolean between 2 controllers using a service. You can
use this post for this option.
You can also use reach parent controller scope from child controller, that can be done if ng-view will be nested in the outer controller. You can use this post for option 3.
I am an angular beginner & trying to introduce angular in a legacy application. The page structure looks like this
<html ng-app="demoApp">
<div class="static-parent">
<div class="dyanamic" ng-controller="SimpleController">
<ul>
<li ng-repeat="cust in customers">
{{cust.name}} - {{cust.city}}
</li>
</ul>
</div>
</div>
</html>
The "dyanamic" div is added to dom when a certain button is clicked.
As this controller div is being added dynamically, i tried to load angular afterwards by calling angular bootstrap
angular.bootstrap(document,['demoApp']);
After running the above statement,
3 Li elements are getting created in the dom
But no data is being seen
on the web page. The Li elements are empty
>> angular.element(".dynamic").scope().customers; returns 3 customer objects as expected.
>> angular.element(".dynamic").scope().$apply(); did not help either.
Can you please suggest where I am going wrong? Tried other answers on stackoverflow but didn't seem to help.
Controller code:
//setting up controller
var demoApp = angular.module("demoApp", []);
var controllers = {};
controllers.SimpleController = function($scope){
$scope.customers = [{name:'dave', city:'auckland'},{name:'abe', city:'City2'}, {name:'ram', city:'City3'}];
};
demoApp.controller(controllers);
Code for adding the div dynamically:
var template = Handlebars.compile( $("#template-content-content-container").html() );
$("static-parent").html(template(data));
angular.bootstrap('.page .row', ['demoApp']);
Angular version: 1.0.6
On 1.2.28, calling angular.bootstrap(document,['demoApp']) or angular.bootstrap('.dynamic',['demoApp']);`
is giving
Error: error:btstrpd
App Already Bootstrapped with this Element
Following is the browser screenshot -
Please, check the third (accepted) answer to this: Angular bootstrapping after load of html
(direct link: Loading an AngularJS controller dynamically)
I think, you have to "compile" anything, which is added after a first 'bootstrap' call
Also, I've made this fiddle yesterday to describe my trouble, I think it fits yours.
http://jsfiddle.net/21neg0ox/
var app = angular.module('app', []);
angular.element(document).ready(function () {
angular.bootstrap(document, ['app']);
});
//c1
app.controller('c1', ['$scope', '$compile', c1Fn]);
app.controller('c2', ['$scope', '$compile', c1Fn]);
function c1Fn($scope){
$scope.isAlive = 'is alive';
}
setTimeout(wtf, 500);
function wtf(){
var myLovelyHTML = '<div ng-controller="c2">c2 {{isAlive}}</div>';
document.getElementById('c2-wrap').innerHTML = myLovelyHTML;
}