Using ng-model (or other solution) without breaking MVC paradigm - javascript

I recently asked a question on Stack where I was trying to obtain a DOM element's ID via AngularJS' ng-click. Essentially the answer which was given (with an important caveat was):
Use event.currentTarget vs event.target to get the element to which the binding was registered, BUT this is an atypical way to do it because it ties the controller to the DOM when ideally the controller should know nothing about the DOM.
I'm starting to get a better idea of this now, but would like some further help / clarification.
Using ng-repeat I dynamically render a number of tiles being pulled from a database and present them to the user for selection. When a user clicks on a given tile I want to be able to 'know' that element's ID (or some unique identifier key) so that I can pass it into my javascript / java and then retrieve the details for said key where they are rendered in a different, more detailed view.
I've started to research ng-model which supports the two-way MVC idea, but I'm stuck. You can see below that I'm dynamically rendering each tile with a different ng-model value which equals the tile's database key. Is this the solution I want? If so, how can I reference the ng-model value in javascript? Or if I do that, am I breaking the MVC again? If that's the case, what would be a solution which preserves the model?
Cheers
HTML:
<div ng-repeat="tile in tileResult">
<div ng-model={{tile.id}} ng-click="handleThisElement($event); changeView('panel3')" class="container-fluid btn-default tile">
<div class="row">
<div class="col-xs-9">
<div class="row">
...
</div>
</div>
<div class="col-xs-3 tile-stats">
<div class="row text-center">
...
</div>
</div>
</div>
</div>
</div>

Tie the ng-model to an object, best if it's something in the repeater. Also, ng-model is generally used with an input... not on a div, so I'm not sure what you're trying to achieve here.
You may want to initialize the value to the index (or some other default) if the value doesn't exist, this will avoid null pointers when you want to change the value later.
<div ng-repeat="tile in tileResult">
<div ng-model="tile.someDataValue" ng-init="tile.someDataValue = $index" ng-click="handleThisElement($event); changeView('panel3')" class="container-fluid btn-default tile">
...
</div>
</div>
To later reference the value, you can just access your tileResult object at the appropriate value/index
Ex:
console.log($scope.tileResult[0].someDataValue);
Or you can access the entire 'tile' on click by passing the 'tile' into a function. Ex:
<div ng-model="tile.someDataValue" ng-init="tile.someDataValue = $index" ng-click="someFunction(tile); handleThisElement($event); changeView('panel3')" class="container-fluid btn-default tile">
$scope.someFunction = function(someTile){
console.log(someTile.id, someTile); // log the id, then the entire object
}

If I understand you correctly, you want to be able to access the unique identifier for each tile.
This can easily be done without Ng-Model! One easy fix would be to set the id of each element with the unique identifier:
<div ng-repeat="tile in tileResult">
<div id="{{tile.id}}" ng-click="handleThisElement($event); changeView('panel3')" class="container-fluid btn-default tile">
<div class="row">
This way, when you pass $event to your handleThisElement function, you are able to access the id in the same way you have before.

Related

Apply Changes for <div> using a javascript

This is my div class.
<div class="panel-body relative" ng-attr-id="{{{{$parent.p.cameraId}}}}"></div>
How to replace the "string" of below codes with above ng-attr-id?
var target = document.getElementById('string');
do some code modification
<div class="panel-body relative" id='string' ng-attr-id="{{{{$parent.p.cameraId}}}}"></div>
id='string'
var target = document.getElementById('string').getAttribute('ng-attr-id');
See https://docs.angularjs.org/guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes
<div class="panel-body relative" ng-attr-id="{{$parent.p.cameraId}}"></div>
The value comes from your scope! and gets interpolated. You can't change the view when its already rendered. Because the output of your code will be something like:
<div class="panel-body relative" id="foo"></div>
So that attribute is not there anymore. You have to change your parent scope value. The parent you should be able to reach with a service or so. If you are new with developing and starting with AngularJS personally i would skip that ancient thing and move to Angular.
From your question i see that you want to change things according to the cameraId but then you should simply use views and not mix vanilla JavaScript with Angular.

loading on specific div in loop vuejs

This is my first question in this forum. I had been using jquery for a while but now I recently shifted to vuejs and found it's awesome.
Here is a little hitch I am having. The problem is I have to set v-loading on buttons in a loop and when I click I need it to be true (i.e starts showing). This is how I have done it but I don't know how to trigger it.
<div class="col-sm-12" style="padding:0;" v-for="follow_request in follow_requests" v-loading.body="true">
<div class="col-sm-4">
<img class="img-circle" :src="follow_request.user.image | appendBaseUrl"
style="height:60px;"/>
</div>
</div>
v-loading.body="true"
I need to make it true and false on click, but only this specific div.
I typically suggest adding a property to the object that you are iterating over that represents the state. For each of the follow_request objects in your follow_requests array, add the property, loading.
Then you can use it in your template.
<div class="col-sm-12"
style="padding:0;"
v-for="follow_request in follow_requests"
v-loading.body="follow_request.loading"
#click="follow_request.loading = !follow_request.loading>

What is Data-navigate and data-position in html

<section id="attorneys" data-navigate="attorneys" data-position="-126">
<div class="attorneys-content">
<div class="container">
<div class="clear clearfix"></div>
<div class="col-sm-12 ">
<div class="typography style2 webkit" data-animate="fadeInUp">
<i class="fa fa-university" aria-hidden="true"></i>
<h3 class="text1">Meet here</h3>
<h1 class="text2">Our Attorneys</h1>
</div>
</div>
</div>
</div>
</section>
what is the use of the data elements in code , where are these linked and how works
Typically data- attributes are used to give extra meaning to elements and are commonly accessed via javascript.
The values can be retrieved via getAttribute() or dataset property on the element.
HTML5 is designed with extensibility in mind for data that should be associated with a particular element but need not have any defined meaning. data-* attributes allow us to store extra information on standard, semantic HTML elements without other hacks such as non-standard attributes, extra properties on DOM, or Node.setUserData().
See here for more information:
https://developer.mozilla.org/en/docs/Web/Guide/HTML/Using_data_attributes
Data is attribute using to store custom data.
You can access it using jQuery as $('div').data('key') which return content of attribute data-key <div data-key="xoxo">.
Or set: $('div').data('key', {'data':1}).
Nice thing about data attribute is that it can keep original data format (other html attributes can't), so you can store object, arrays and don't need to parse them after read.
** keep in mind that if you update data from js content won't be visible from web console view.

angular-ui > ui-utils > ui-scroll does not work (v. 0.1.0)

I am using this: http://angular-ui.github.io/ui-utils/ and to be more specific this:https://github.com/angular-ui/ui-utils/blob/master/modules/scroll/README.md
however it does not seem to work. Here is an example:
<div ng-scroll-viewport style="height:240px;" class="chat-messages">
<div class="chat-message" ng-scroll="chat in chats">
<div ng-class="$index % 2 == 0? 'sender pull-right' : 'sender pull-left'">
<div class="icon">
<img src="{{chat.img}}" class="img-circle" alt="">
</div>
<div class="time">
{{chat.time}}
</div>
</div>
<div ng-class="$index % 2 == 0? 'chat-message-body on-left' : 'chat-message-body'">
<span class="arrow"></span>
<div class="sender">{{chat.name}}</div>
<div class="text">
{{chat.msg}}
</div>
</div>
</div>
</div>
But All I get in HTML is this :
<div class="chat">
<div class="chat-messages" style="height:240px;" ng-scroll-viewport="">
<!--
ngScroll: chat in chats
-->
</div>
If I replace ng-scroll with ng-repeat, it works perfectly. But chats need scroll bars, so... How can I get one? :)
The documentation of ngScroll directive had also tricked me into simply replacing ng-repeat by ng-scroll. Unfortunately, it turned out not as simple as that, see also the small, working example at http://plnkr.co/edit/fWhe4vBL6pevcuLutGC4 .
Note that
"datasource" (or whatever object you want to iterate over for the contents of the scroll list) must implement a method "get(index,count,success)" that calls success(results), see hXXps://github.com/angular-ui/ui-utils/blob/master/modules/scroll/README.md#data-source
The array must have exactly count elements. Otherwise, no scroll window/bar will ever show, which can be very irritating!
Although UI.Utils says it has no external dependencies, ui.scroll has actually a dependency on either ui.scroll.jqlite, or jQuery. So make sure to list both ui.scroll and ui.scroll.jqlite in your module definition which contains the controller with datasource object (and load their .js files, or load ui-utils.js which contains both), see https://github.com/angular-ui/ui-utils/blob/master/modules/scroll/README.md#dependencies
Be careful when your server is sending some Content Security Policies (CSP). Maybe turn them off while trying to get ng-scroll to work first, then re-apply CSP and tune the policies accordingly for ui.scroll to work.
One way of getting a scroll is to use CSS, set overflow-y to scroll and you will get scroll bar.
If you need to scroll to the bottom, play with anchorScroll
http://docs.angularjs.org/api/ng.$anchorScroll.

Unable to specify multiple attributes in handlebar

I am having problem specifying multiple attributes in any class at all.
if I have a key:value like
{"class":"javascript handlebar-js"}
and use it like this
<div class={{class}}><div>
it only spits out
<div class="javascript"><div>
when I want
<div class="javascript handlebar-js"><div>
Sometimes I have one class sometimes I have multiple classes
Is there any other way to do this besides putting all classes inside an array and using a with + each statement to move through each class and cramping up my object with unnecessary arrays? Not that I am sure if using said method would work.
any help would be appreciated
As said by Pointy, enclosed class definition into simple or doubles quotes.
Based upon this data ({"className":"javascript handlebar-js"}),
<div class="{{className}}"> </div> will produce <div class="javascript handlebar-js"></div>
<div class={{className}}> </div> will produce <div class="javascript" handlebar-js></div>
The two results will not be interpreted in the same way in the browser.

Categories

Resources