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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.