0

I'm afraid this question is pretty stupid....

Using the {{current.name}} syntax I can show the name of $scope.current in the view. I set current when I switch from the list view (/mythings) to editing an item (/mythings?id=someId).

Actually this is redundant as I have the information both in the $location and in $scope.current. This redundancy makes it more complicated to understand, so I'd like to get rid of it.

I replaced current by a current item returning function and hoped it would work (like it does in many other cases). But it doesn't, I need to write {{current().name}} everywhere, which I tend to forget.

Maybe I'm doing it all wrong? I'm a beginner here.

Is there a way to make it work? Somehow bless current so it always gets evaluated before use?

8
  • I am having trouble understanding the question. If you were on /mythings, what is it you want to see bound to the screen? Commented Apr 6, 2014 at 16:52
  • @drew_w: I don't really understand my question either.. I'm just a confused newbie here. But I hope, I explained the redundancy thing clearly. When I'm on /mythings, then there's nothing as there's no selected item (current is undefined). When I'm on /mythings?id=someId, then current.id = someId. This is the redundancy I wrote about. I could imagine current being a function returning the element with $location.search('id'). Commented Apr 6, 2014 at 16:57
  • You can have a different controller for list and the detail view. Then the detail view controller will only have current. Commented Apr 6, 2014 at 16:59
  • I don't really see that much of a redundancy. You either have to bind scope's property (current) to some value that already exists or you have to declare a new function (current()) and call it multiple times per digest loop. I think the second alternative introduces more redundancy than it avoids. Commented Apr 6, 2014 at 17:55
  • @ExpertSystem: My problem with the variable is that I have to keep it in sync with $location.search while the function would always produce the correct result. I was trying to remember if the last state of a page was "list" or "detail" by storing current in a service and it got out of sync with the location (no surprise). Then I tried to update the $location.search based on current and got lost. Maybe I just need a break... ;) Commented Apr 6, 2014 at 19:05

1 Answer 1

1

Both alternatives discussed have pros and cons:

  1. Using a property (current) is easier (and more natural) to reference in the view, but it needs to be manually kept in sync with the location.

  2. Using a function (current()) takes care of the keeping in sync issue, but is less intuitive.

All things considered, I would value the auto-syncing feature higher and go for the second alternative (current() function).


But, what if we could get a third option that combines the best of both worlds ?
And in fact we can :)

We can use the concept of Object Properties, introduced by ECMAScript 5, and define some "computed properties" for our $scope (or service?).

Without getting into much detail (see the docs for more details), we could augment a scope like this:

.cotroller('someCtrl', function ($location, $scope) {
    Object.defineProperty($scope, 'current', {
        get: function () {
            return {
                name: $location.path();
                id: $location.search('id');
            };
        }
    });

Now, we can access $scope.current.name and $scope.current.id as if current were a normal property of $scope (intuitiveness !) and current will be automatically computed based on the current location (auto-sync !).
Thank you ECMAScript 5 :)

This article provides a simple and clear introduction to the concept.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.