If you are really keen on building it like that, you can do it through a custom built directive and custom child-attributes, see the sample running on plunkr: http://plnkr.co/edit/piwNFpkeb5AxcbQ1j2oY?p=preview
On Sunday, December 29, 2013 12:51:41 PM UTC, Богдан Цимбала wrote: > > Some comments inline > > Субота, 28 грудня 2013 р. 04:41:38 UTC+1 користувач Daniel Tabuenca > написав: >> >> This is a common question/concern by those seeing angular for the first >> time. In a sense, it seems as though we've gone backwards in time when we >> used to do things like: >> >> <div onclick="doSomething()"> >> >> About the time that jquery started becoming popular, a lot of the >> web-development community got sold on "unobtrusive javascript" which a >> large part of it meant you would clean the dom from all javascript and then >> attach javascript handlers entirely from within a script. One of the >> greatest benefits of this approach as it evolved is that it freed us to a >> large extent form having to define our handlers globally. >> > That's only small part of the top of the iceberg. For me other problems of > these approach are much more important, global functions is just one > maifestation. It all comes down to one and the same problem (as always) - > no separation of concerns. You clearly have at least two tasks when > presenting UI to user: visualize (output) and behave (input). Behavior can > even be a subject to aspect oriented programming as it can become a cross > cutting concern (e.g. resizing and drag and drop). It's always a good idea > to separate those concerns. BTW I'm not per sei following unobtrusive as > I'm long time forgot it's concepts even. > >> We could now create our handlers in modularized non-global code and then >> attach them directly to the dom, and this is the main concept with a lot of >> the jquery-based frameworks such as backbone.js. >> >> However, this style of programming did not come without it's downsides. >> While the intent was to keep javascript unobtrusive, in practice both the >> javascript and the dom intruded on each other all over the place. >> >> The dom became filled with extra markup and classes unrelated to style to >> make it selectable as well as to hold state: >> >> <div> >> <span class="show-person-details" data-person-id="42">Person 2<span> >> <div class="person-details hidden" data-person-id="42">This is the >> details</div> >> </div><div> >> <span class="show-person-details" data-person-id="43">Person 1<span> >> <div class="person-details hidden" data-person-id="43">This is the >> details</div> >> </div> >> >> Well two things here: > * even in this incarnation it's still "ok" to declare in the view the > support of some behavioral interface, it's not how I prefer to do it but > it's better then inlining the implementation on that place > * in proper setup you can easily get away from view even bothering > about knowing that id - your view is bound to a model which holds the id > and your behavior can read that from model, the only requirement from the > view is to mark the action blocks, but again even that could be replaced > with mini behaviors and scopes. > >> The javascript became littered with complex selector expressions, css >> classes >> > again I think quite good abstract interfacing (you can easily scale to XML > like that for example). > >> , and lots of dom manipulation code: >> >> $('.show-person-details').click(function(ev){ >> var personSpan = $(ev.target); >> var personId = personSpan.data("person-id"); >> $('.person-details[data-person-id='+personId+']).removeClass("hidden"); >> }); >> >> That's not per sei necessary if you have good view technology which > takes model as input and renders it - you code changes quite drastically to > a more readable and scalable version. And this example is not much better > than previous - you still define one global listener where everything is > bulked together, it's maybe unobtrusive but not properly separated. > >> This is just a simple example, on many a real-world project this can get >> much worse. In any case the dom clearly intruded into the javascript, and >> the javascript intruded into the dom (in the form of unecessary selectors >> and data attributes, hidden inputs, etc...). >> >> The philosophy of angular is to elminate the real fundamental issue we >> had with onclick= style handlers which is the fact that they were >> global. It does this by creating a scope hierarchy (controlled by >> Controllers and Directives) that allows you to map state neatly and in a >> modular fashion onto the DOM tree we are all familiar with. >> > As I'm mentioning - it's not what I would like to achieve - I would like > to keep behavior and rendering separated and I would like to be able to use > OO means to model and encapsulate behavior (even for cross cutting > behavior). Behavior can span multiple events and can have own presenataion > models, it is a mess to take all behavior event handling (and possible > state) bulk it all together and then mash it into the view. It hurts all > aspects that I'm striving for. > >> I can do the equivalent of the above example purely in the html (assuming >> that persons object already exists in our scope): >> >> <div ng-repeat="person in persons"> >> <span ng-click="person.detailsVisible= true">{{person.name}}<span> >> <div ng-show="person.detailsVisible">{{person.details}}</div></div> >> >> This is very easy to understand, even for someone who's never used >> angular. Simply by looking at the markup I can tell exactly what the >> behavior of this will be. Furthermore, I've removed the need to do any >> custom javascript logic or dom manipulation in order to show/hide the >> details. >> > Now few things about this: > * say someone puts 0 or -1 or {} or [] or whatever other value there - > which test of yours fail? > * what stops me from starting to write 'person.detailsVisible = > person.details ? !person.detailsVisible : false;' (and again go untested)? > * so say nothing stoped me from doing above how do I support touch? I > would guess in Angular you would push it in scope and mix data with > behavior, well ok... > * what if I have not only person but also group or some other entity > and and it happens to also have details but the display is quite different > - what is the appropriate structuring in angular to achieve this quite > simple structure? > > It just feels like a natural structuring for me to have separation between > Presentation, View and Behavior. > > While it might not be incredibly difficult in the simple jQuery example >> above to tell what the code might do, I've often have had to jump on >> existing large projects where figuring out what the page is supposed to do >> is an incredibly difficult task. The DOM is litered with classes, but which >> ones are for style? Which ones are to make it easier to use selectors to >> bind some event? How do I know what's clickable, and how different parts of >> the page might be related? How am I supposed to know that deep down in some >> obscure part of the code some event is bound that does something I did not >> expect? >> > > That's essential problem with lack of separation of concerns: > * when resolving problem from rendering space (how to visualize > something or why it's not visualized as expected) you look into view > (templates, HTML, CSS, media) > * when resolving problem from behavioral space (how to react on input, > why reaction on input is incorrect) you look into behavior (JS behavior > modules) and it's interface part in view (templates) > * when resolving problem from presentational space (what information to > present to user, how user can reach needed goals) you look into your > presentation model (JS modules) > > And of course it should be a clear syntax where the binding points are. I > prefix classes in HTML with js- to indicate that they are behavioral > markers, plus CSS is linted against using classes with those prefixes. As I > don't really care about validators (we use XHTML anyway) I could use just > custom attributes to simplify things. > >> Sure, with discipline, great care, and tight organization you can >> alleviate some of the pain, but I've been on projects with very talented >> developers and strict code organization that still eventually become >> somewhat of a mess. >> >> One of the difficulties I think you will face is in trying to integrate >> with your existing way of doing things. >> >> While angular itself is fairly low-level, flexible, and certainly not as >> perscriptive as some other frameworks (e.g. ember.js), you will still run >> into quite a bit of friction if you don't do things "the angular way". >> >> What people often mean when they say "the angular way" is really just >> designing the application in a more declarative way. This is fundamentally >> different than the imperative patterns people are used to from using jQuery. >> > What I describe is purely declarative separation, even behavior classes > can be structured by convention to have declarative look and be > inspectable. > >> In the first person/details example above the code is entirely >> imperative. The click calls a click handler which instructs the browser to >> lookup a piece of dom and hide it. The click is tightly coupled to what >> must happen as the result of the click. >> >> In the angular (declarative example) we break things up into independent >> actions. The click simply sets the state detailsVisible on the person. >> The details simply is setup to show the details whenever the detailsVisible >> flag is true. It is completely decoupled from the click action. It doesn't >> care whether the detailsVisible flag was set by a click handler, by >> javascript code, by some bound checkbox, loaded from the server that way, >> etc.... >> > What I describe is the quite same, just the way how actually that > "detailsVisible" is changed is moved into presentation model into something > like toggleDetails() but than how is that action triggered is encapsulated > in behavior entity. So your concept of declarative view stays there it is > automatically updated cause the scope changed, but the only thing it would > describe on how is that happen from that view is by mentioning behavior > class name. > > A hypothetic syntax in Angular: > > <ng:repeat items="persons" var="person" behavior="ExpandableBlock"> > <span class="js-expandable-block-toggle">{{person.name}}<span> <div > ng-show="person.detailsVisible">{{person.details}}</div></ng:repeat> > > In any case, what I understand from Majid is I should use directive for > that. That's kinda clear, but that's what I also miss explicit concept for > behavior and rather very low level processing instructions. So I already > tried to evaluate how I can bind my behavior classes to some custom > directive, but for now what I fail to see is the life cycle of directive. > > For my purposes as described above I would be attaching the behavior to > each item. From angular I get the creation phase which is good, but now > when the list of persons change, I need to dettach the behavior instance > from ghost HTML (and detach in genral, think for example when it has global > event listening to close drop down or something). > > So first question in my journey is how do I achieve that? > -- You received this message because you are subscribed to the Google Groups "AngularJS" group. To unsubscribe from this group and stop receiving emails from it, send an email to angular+unsubscr...@googlegroups.com. To post to this group, send email to angular@googlegroups.com. Visit this group at http://groups.google.com/group/angular. For more options, visit https://groups.google.com/groups/opt_out.