Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic data-binding in AngularJS

I'm building an AngularJS app and I have ran into an issue. I have been playing with the framework for a while and I have yet to see documentation for something like this or any examples. I'm not sure which path to go down, Directive, Module, or something that I haven't heard of yet...

Problem:

Basically my app allows the user to add objects, we will say spans for this example, that have certain attribute's that are editable: height and an associated label. Rather than every span have its own dedicated input fields for height and label manipulation I would like to use one set of input fields that are able to control all iterations of our span object.

So my approx. working code is something like this:

<span ng-repeat="widget in chart.object">
    <label>{{widget.label}}</label>
    <span id="obj-js" class="obj" style="height:{{widget.amt}}px"></span>
</span>
<button ng-click="addObject()" class="add">ADD</button>

<input type="text" class="builder-input" ng-model="chart.object[0]['label']"/>
<input type="range" class="slider" ng-model="chart.object[0]['amt']"/>

The above code will let users add new objects, but the UI is obviously hardcoded to the first object in the array.

Desired Functionality:

When a user clicks on an object it updates the value of the input's ng-model to bind to the object clicked. So if "object_2" is clicked the input's ng-model updates to sync with the object_2's value. If the user clicks on "object_4" it updates the input's ng-model, you get the idea. Smart UI, essentially.

I've thought about writing a directive attribute called "sync" that could push the ng-model status to the bound UI. I've though about completely creating a new tag called <object> and construct these in the controller. And I've thought about using ng-click="someFn()" that updates the input fields. All of these are 'possibilities' that have their own pros and cons, but I thought before I either spin out on something or go down the wrong road I would ask the community.

Has anyone done this before (if so, examples)? If not, what would be the cleanest, AngularJS way to perform this? Cheers.

like image 412
Scott Sword Avatar asked Mar 04 '13 00:03

Scott Sword


1 Answers

I don't think you need to use a custom directive specifically for this situation - although that may be helpful in your app once your controls are more involved.

Take as look at this possible solution, with a bit of formatting added: http://jsfiddle.net/tLfYt/

I think the simplest way to solve this requires: - Store 'selected' index in scope - Bind ng-click to each repeated span, and use this to update the index.

From there, you can do exactly as you proposed: update the model on your inputs. This way of declarative thinking is something I love about Angular - your application can flow the way you would logically think about the problem.

In your controller:

$scope.selectedObjectIndex = null;

$scope.selectObject = function($index) {
    $scope.selectedObjectIndex = $index;
}

In your ng-repeat:

<span ng-repeat="widget in chart.object" ng-click="selectObject($index)">

Your inputs:

<input type="text" class="builder-input" ng-model="chart.object[selectedObjectIndex]['label']"/>
<input type="range" class="slider" ng-model="chart.object[selectedObjectIndex]['amt']"/>
like image 185
Alex Osborn Avatar answered Oct 04 '22 23:10

Alex Osborn