Plug angularjs directive into component - angularjs

I currently have a generic list component and I want to add, depending on where I use it, different callbacks for adding/removing/updating items to that list.
My current implementation looks like this:
<div list-callback1>
<generic-list
add-callback="listCallback1.add()"
update-callback="listCallback1.add(id, name)"
delete-callback="listCallback1.delete(id)"></generic-list>
</div>
My question:
Is there a way to decrease nesting? Because when I add the directive directly to my component I get a compile error.

Ok, it was a different problem.
I had scope: true in my list-callback1 directive.
After removing that, all works fine. Thanks for the help
Sorry I couldn't post more code, but I am restricted by my employer ;)

Related

Bootstrap Typeahead Async - multiple values

Im trying to implement Bootstrap Typeahead in my AngularJS project and I came across an issue with values.
Im loading the content via $http from my Django API server. For now, I can lookup for any item I want and display it's name, but what I need is to display "title" but return "id" via ng-model back to the controller.
Do you have any working example of doing this?
http://pastebin.com/xtype9J4
I'm assuming you are using https://angular-ui.github.io/bootstrap/#/typeahead, so I'd suggest having a look at the last example.
Looking at the DOM, your code could look something like this:
uib-typeahead="company as company.name for company in getCompanies($viewValue)"
This pretty much contains exactly what you need. Additionally, take a look at https://docs.angularjs.org/api/ng/directive/select and https://docs.angularjs.org/api/ng/directive/ngOptions for further examples, as AngularUI has a similar (if not identical) approach.

master Detail with ui-router of angular

I am new to angular and was looking for an example of a master detail. I found one: http://embed.plnkr.co/DBSbiV/App.js, but this is using angular's ngRoute. As I heard ui.route is the state of the art kind of way to handle routing due to it is more flexible.
I want to have both master and detail on one template, so I tried to solve it with multiple named views like in https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views. But I now have to problem, that I don't know how to create a link in the master list to the detail view with .. I tried with ... but don't know what to put right here, because I have only one state with multiple views.
Can you tell me whether I'm on the wrong way or what I put into this ref to link to my detail?
Thanks in advance
Markus
You don't actually need named views for this. Just nested views. Lets imagine you have a list of blog posts. You have one state called blogs. And another state called blogs.edit, which takes a parameter of the postId.
Your blogs.html (the master list) could look something like this:
<a ng-repeat="post in blog.posts" ui-sref="blogs.edit({postId: post.Id})">{{post.title}}</a>
<div ui-view></div>
This will render a list of anchor tags, and a nested details view under.

Linking to external URL with different domain from within an angularJS partial

All I am trying to do is include an anchor tag inside the html of a partial that links to an external site. Were this standard html, the code would simply be:
google
As simple as this is, I cannot seem to find a working solution for getting past angular intercepting the route (or perhaps replacing my anchor with the https://docs.angularjs.org/api/ng/directive/a directive unintentionally?).
I have scoured SO and the rest of the web and seen a myriad of solutions for dealing with: links within the same domain, routing within the SPA, routing within a page (ala $anchorScroll) but none of these are my issue exactly.
I suspect it may having something to do with using $sce but I am an Angular n00b and not really sure how to properly use that service. I tried the following in my view controller:
$scope.trustUrl = function(url) {
return $sce.trustAsResourceUrl(url);
}
with the corresponding:
<a ng-href="{{ trustUrl(item) }}">Click me!</a>
(as described here: Binding external URL in angularjs template)
but that did not seem to do the trick (I ended up with just href="{{" in the rendered page).
Using a plain vanilla anchor link like this:
google
also failed to do the trick (even though some online advised that standard href would cause a complete page reload in angular: AngularJS - How can I do a redirect with a full page load?).
I also tried adding the target=_self" attribute but that seemed to have no effect either.
Do I need to write a custom directive as described here?
Conditionally add target="_blank" to links with Angular JS
This all seems way too complicated for such a simple action and I feel like I am missing something obvious in my n00bishness, at least I hope so because this process is feeling very onerous just to link to another url.
Thanks in advance for any solutions, advice, refs or direction.
It turns out that I did in fact have all anchor links in the page bound to an event listener and being overridden. Since that code was fundamental to the way the page worked I did not want to mess with it. Instead I bypassed it by using ng-click to call the new url as follows:
HTML:
<a class="navLinkHcp" href="{{hcpurl}}" title="Habitat Conservation Plan" target="_blank" ng-click="linkModelFunc(hcpurl)">Habitat Conservation Plan</a>
Controller:
$scope.hcpurl = 'http://eahcp.org/index.php/about_eahcp/covered_species';
$scope.linkModelFunc = function (url){
console.log('link model function');
$window.open(url);
}
And voila! Good to go.
Thanks again to KevinB for cluing me in that this was probably the issue.

Using Angular-Bacons $scope.$watchAsProperty(property) in Angulars ng-repeat

I´m trying to find a good way to use Baconjs together with Angularjs in conjuctions with Angular-Bacon.
Now digesting from Bacon to the Angular scope works perfectly fine but I´m stumbling with Angular-Bacons $scope.$watchAsProperty(property) within Angulars ng-repeat:
Let´s say I have the Angular scope $scope.databaserecords and render it out with:
<div ng-repeat="record in databaserecords">
Each of the records has a record.checked property and I want to handle all checked records together in one Bacon stream, for example to add a certain tag to all records at once.
At this point using $scope.$watchAsProperty(databaserecords) I get no Bacon events when checking or unchecking certain records, so how could I accomplish to receive these changes back in Bacon?
I might also mention, that using $scope.$watchAsProperty(property) out of ng-repeat, for example for input fields, works well without any problem.
Thanks for your help! :)
If I've understood correctly, your actual databaserecords remains the same throughout the scope, so you'll need to invoke $watchAsProperty with the objectEquality argument set to true:
$scope.$watchAsProperty("databaserecords", true)
By default angular opts to compare objects with a simple object equality check. In your case the list object remains the same, so a deeper check is necessary. This is already implemented in angular-bacon but it seems I've omitted it from the docs.

Having a set of checkboxes map to a nested array

I am working on a SPA that pulls in customer data from one $resource call, and gets some generic preference data from another $resource call.
The preference data is sent as an array, which I want to use to populate a series of checkboxes, like so:
<div ng-repeat="pref in fieldMappings.mealPrefs">
<input type="checkbox"
id="pref_{{$index}}"
ng-model="customer.mealPrefs"
ng-true-value="{{pref.name}}" />
<label class="checkbox-label">{{pref.name}}</label>
</div>
When a user clicks one or more checkboxes, I want the values represented in that array of checkboxes to be mapped to an array nested inside a customer object, like so:
.controller( 'AppCtrl', function ( $scope, titleService, AccountDataService ) {
// this is actually loaded via $resource call in real app
$scope.customer = {
"name": "Bob",
"mealPrefs":["1", "3"]
};
// this is actually loaded via $resource call in real app
$scope.fieldMappings.mealPrefs = [
{'id':"1", 'name':"Meat"},
{'id':"2", 'name':"Veggies"},
{'id':"3", 'name':"Fruit"},
{'id':"4", 'name':"None"}
];
});
I have tried setting up ng-click events to kick off functions in the controller to manually handle the logic of filling the correct part of the customer object model, and $watches to do the same. While I have had some success there, I have around 2 dozen different checkbox groups that need to be handled somehow (the actual SPA is huge), and I would love to implement this functionality in a way that is very clean and repeatable, without duplicating lots of click handlers and setting up lots of $watches on temporary arrays of values. Anyone in the community already solved this in a way that they feel is pretty 'best practice'?
I apologize if this is a repeat - I've looked at about a dozen or more SO answers around angular checkboxes, and have not found one that is pulling values from one object model, and stuffing them in another. Any help would be appreciated.
On a side-note, I'm very new to plunkr (http://plnkr.co/edit/xDjkY3i0pI010Em0Fi1L?p=preview) - I tried setting up an example to make it easier for folks answer my question, but can't get that working. If anyone wants to weigh in on that, I'll set up a second question and I'll accept that answer as well! :)
Here is a JSFiddle I put together that shows what you want to do. http://jsfiddle.net/zargyle/t7kr8/
It uses a directive, and a copy of the object to display if changes were made.
I would use a directive for the checkbox. You can set the customer.mealPrefs from the directive. In the checkbox directive's link function, bind to the "change" event and call a function that iterates over the customer's mealPrefs array and either adds or removes the id of the checkbox that is being changed.
I took your code and wrote this example: http://plnkr.co/edit/nV4fQq?p=preview

Resources