>> <div ng-repeat="person in persons">
>> <span ng-click="person.detailsVisible= true">{{person.name}}<span>
>> <div ng-show="person.detailsVisible">{{person.details}}</div>
>> </div>
>>
>>
>> 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)?
>
E2E tests *could* catch this, although I agree with you. In practice I
don’t generally write code like that, and limit expressions to either
properties or function calls, making things testable at the controller
level.
* 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?
>
For behavior that is re-usable and generic, the proper thing to do would
be to write a directive with its specific behavior, like in Diogo’s example.
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.
>>
> This makes sense, but but the “behavior” abstraction is adding an
additional level of indirection that is not always necessary or useful.
When It comes to cross-cutting behaviors that can apply generically in
multiple places, then it makes perfect sense to abstract things out into
behaviors (which in angular would be to make directives for these
things).However,
for custom behavior that can not be shared, I see no fundamental problem in
using angular’s event directives. For example, if we wanted a button to
mark a customer as preferred:
<button ng-click="customer.markAsPreferred()">Make Preferred</button>
I don’t really see this as having “behavior in the view”, because the
behavior implementation is in the customer object, the ng-click is just an
expressive binding. When looking at the template I know (without having to
go through any extra level of indirection), that if I click on that button
the customer will be marked as preferred.
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.
>
I’m not sure I understand what you mean by “low-level processing
instructions”. I don’t know how you’re behaviors are currently implemented
but directives are really just a function where you are given a scope and
an html element and you do whatever you want.
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?
>
The link function of a directive gets run once for each node that the
directive is on. Any further code executed by the directive is in response
to any event listeners or watches that you have setup. If you have setup
listeners on any dom elements, it is up to you to unbind these when they
are no longer needed in order to prevent memory leaks. This is often done
by listening for the $destroy event on the scope and unbinding in the
handler. Directives that introduce and remove DOM should call
`scope.$destroy()` before the dom is removed. Angular directives like
`ng-repeat` and `ng-if` already do this.
--
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.