I love the simplicity, but hate when it it burns me due to a typo or
an assignment made in the wrong scope.
Examples:
1) in the code below when the link is clicked on a new "foo" scope
variable is created and 23 is assigned to it.
<body>
<a href ng:click="foo=23">click</a>
foo={{foo}}
</body>
if I make a slight typo a spell the last {{foo}} as {{fool}} nothing
will ever get printed.
2) in this second example, I initialized foo to be 23, then created a
bunch of links with a repeater and set ng:click handler to reset the
foo variable to one of 1,2,3 or 4 depending on which of the four links
is click. Unfortunately the foo={{foo}} will never reflect the changes
made by ng:click, because the repeater creates a new child scope for
each iteration and the "foo=i" assignment is evaluated on this child
scope and not on the parent scope where foo remains 23.
<body ng:init="foo=23">
<a href ng:repeat="i in [1,2,3,4]" ng:click="foo=i">click</a>
foo={{foo}}
</body>
To avoid both of these issues, I'm thinking that it might be a good idea to:
1) require scope variables that were not initialized in controllers to
be declared in the view before they are used
2) angular should throw an error when an assignment is made in the
view to an unknown variable
3) all assignments should be evaluated on the scope on which the
left-hand-side variable was first declared
I'm not set on the syntax, but a simple proposal for fixing both
examples above would be:
1)
<body ng:var="foo">
<a href ng:click="foo=23">click</a>
foo={{foo}}
</body>
or
<body ng:init="var foo">
<a href ng:click="foo=23">click</a>
foo={{foo}}
</body>
2)
<body ng:var="foo=23">
<a href ng:repeat="i in [1,2,3,4]" ng:click="foo=i">click</a>
foo={{foo}}
</body>
or
<body ng:init="var foo=23">
<a href ng:repeat="i in [1,2,3,4]" ng:click="foo=i">click</a>
foo={{foo}}
</body>
How do you feel about this change? Is it just me that think that this
change would be good? Do you have any other suggestions or opinions?
cheers,
Igor
Here is a newcomers perspective.
I love the fact that I can assign to undeclared vars in the view. I
often use it in combination with ng:show for simple things.
Example 1 is not that big of a deal but I guess it would be nice to
get an explicit error message if I make a typo.
Example 2 is where I would get confused. I would expect Angular to
(mis)behave like Javascript and put foo in global scope. It would
really be helpful to get an error there.
As for the syntax I don't have any strong opinion but I think I like
ng:var better. How would this look if I want to declare multiple vars?
Would I use multiple ng:var/ng:init or put all declarations in a
single? It would be good if one is able to put new-lines in the code
if I want to declare a bunch of them.
In summary I vote this would be a good change!
/Mårten
2011/1/4 Igor Minar <iim...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups "Angular" group.
> To post to this group, send email to ang...@googlegroups.com.
> To unsubscribe from this group, send email to angular+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/angular?hl=en.
>
>
I think it is useful and generally like the idea.
> I love the simplicity, but hate when it it burns me due to a typo or
> an assignment made in the wrong scope.
This is why one should have automated tests (unit and integration) for
applications.
Runtime checks would require extra variable registrations - which is
in itself error prone. You could register many variables and misuse
them by mistake. On the other hand, you could have a proper test which
would catch unexpected behaviour. You may say that it is easier to
register the variable instead of writing a test, but test is able to
catch much much more than just a typo, this is why people use them in
static typed languages as well.
> 2) in this second example, I initialized foo to be 23, then created a
> bunch of links with a repeater and set ng:click handler to reset the
> foo variable to one of 1,2,3 or 4 depending on which of the four links
> is click. Unfortunately the foo={{foo}} will never reflect the changes
> made by ng:click, because the repeater creates a new child scope for
> each iteration and the "foo=i" assignment is evaluated on this child
> scope and not on the parent scope where foo remains 23.
>
> <body ng:init="foo=23">
> <a href ng:repeat="i in [1,2,3,4]" ng:click="foo=i">click</a>
> foo={{foo}}
> </body>
ng:repeat always creates a new, child scope. From within child scope
you can access parent's foo:
ng:click="parent.foo=i"
foo={{parent.foo}}
--
Regards,
Witold Szczerba
yes, that would have to be supported.
> Would I use multiple ng:var/ng:init or put all declarations in a
> single? It would be good if one is able to put new-lines in the code
you can use new lines already. try:
<body ng:init="foo=1
bar=2">
</body>
/i
Oh yeah, we strongly believe in TDD and writing tests, but I'm talking
about angular views here. You can't write unit or integration tests
for them. That's what we have the end to end tests that cover not only
the view but the whole MVC system and services. However, you generally
don't write end2end tests while working on the code (that's when unit
and integration tests are written). The end2end tests are written once
you have a piece of functionality working and you want to automate the
regression testing. At this point you already caught and resolved all
the typos and other issues in the view and doing that is currently
often harder that in should be.
>
>> 2) in this second example, I initialized foo to be 23, then created a
>> bunch of links with a repeater and set ng:click handler to reset the
>> foo variable to one of 1,2,3 or 4 depending on which of the four links
>> is click. Unfortunately the foo={{foo}} will never reflect the changes
>> made by ng:click, because the repeater creates a new child scope for
>> each iteration and the "foo=i" assignment is evaluated on this child
>> scope and not on the parent scope where foo remains 23.
>>
>> <body ng:init="foo=23">
>> <a href ng:repeat="i in [1,2,3,4]" ng:click="foo=i">click</a>
>> foo={{foo}}
>> </body>
>
> ng:repeat always creates a new, child scope. From within child scope
> you can access parent's foo:
> ng:click="parent.foo=i"
> foo={{parent.foo}}
yes of course, but that requires you to know that the assignment will
happen on the child scope and won't be propagated to the parent scope.
This is not obvious, especially if you are dealing with a larger code
base.
/i
Don't get me wrong, I love TDD, but I can't imagine writing e2e before
my code, that's taking TDD to another level. e2e are much slower than
unit tests and are not intended to be run on every save. besides,
quite frankly I'm not good enough coder to envision the whole MVC
"package" before I write it, which is necessary in order to write an
e2e test before hand. I think I'm not alone though.
I still feel quite strongly about removing support for assigning
values to unknown variables in views. This is exactly what got
javascript in trouble ("a=23" vs "var a=23") and in js it is being
solved via "string mode" which is part of the ES5 standard.
http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
Logging warnings is not good enough IMO, but I could imagine a
compromise where this "strict mode" could be configurable and possible
to turn off just like in javascript (except that the default would be
strict mode).
> WRT 2 - propagation to parent scope:
> When assigning a variable - use the first scope (parent, parent's
> parent, etc...) that has defined this variable...
> This sounds more interesting to me. Do you have an idea how to
> implement that in an efficient way ?
no idea yet, I haven't put much work into this except for some
thinking. walking up the scopes and finding the right scope shouldn't
be too inefficient because the scopes are usually not too deeply
nested. we would have to do some experimentation to see how this works
in practice.
/i
> On the other hand, I'm afraid it's gonna be even more confusing...
>
> But I agree, that angular should provide a better tools for developing
> - better opportunities for debugging.
> These two problems (using wrong variable/scope) are typical problems
> in js, it would be nice to help developers with it...
>
I know cucumber. It's a very nice runner. I'm actually considering
looking into supporting something similar in angular, but it won't
happen any time soon.
I'm still not convinced that writing e2e first will solve either
problem 1) or 2), because even though you'll have failing tests, you
won't be able to easily tell why. And that's what the strict
mode/variable declaration solve.
Yeah, that sounds like a valid approach, it would take more than just
writing ideas into an email to see if it actually works. :-)
Maybe once the resources are done, I'll try to prototype this.
/i