3

Just for note, I know nothing about angularJS, I worked with knockoutJS before and when it comes to angular I am just making assumptions.

I have code like this:

angular.module("umbraco").controller("recallCtrl",
function ($scope, $routeParams) {

    $scope.dcList = { 
        key: "value",
        abc: "aaaa",
        prop: "tadaa!"
    }
});

and markup as follows:

    <div ng-controller="recallCtrl">
        <table class="table table-sm">
            <thead>
                <tr>
                    <td></td>
                    <th>Key</th>
                    <th>Value</th>
                </tr>
            </thead>
            <tr ng-repeat="(key, value) in dcList">
                <td>

                </td>
                <td>
                    <input ng-model="key" />
                </td>
                <td>
                    <input ng-model="value"/>
                </td>
            </tr>

        </table>

        <pre>{{dcList | json}}</pre>
  </div>

So shouldn't output of dcList in the end of html change it's values when I edit corresponding inputs which as I assume are bound to object?

If I am doing something wrong, please advise. I want to create object and be able to change its keys and values.

3
  • You should declare you module like this: angular.module("umbraco", []). You forgot the square parenthesis, you were basically requesting the module not declaring it. I hope it fixes your problem! Commented Sep 21, 2016 at 13:38
  • 1
    ng-model evaluates relative to the current scope which in this case is localized to the ng-repeat. I don't think you can change the key, but the value is getting updated - you're just not seeing it because it's not affecting the dcList object on the parent. In order to update the value of the property on dcList you would have to use ng-model="dcList[key]" within your ng-repeat. Commented Sep 21, 2016 at 13:40
  • @Peter_Fretter not in this case, as I said I know absolutely nothing about angular and how it works, just assumptions, but I am using Umbraco CMS which is build with help of angular, there for I assume that I am injecting my piece of code into existing piece of ng, thats why I don't have ng-app declaration and if I set square parenthesis it just breaks Commented Sep 21, 2016 at 13:49

2 Answers 2

3

The reason your current code isn't working is because the "key" and "value" variables are scoped within the ng-repeat, and no longer refer directly to the original object.

Keeping the "values" attached is easy, just use dcList[key] instead of value. Adding new keys takes a bit more work; here I've attached an ng-blur to each "key" field which will init a new key when the field blurs. (ng-change would create a new field on every keystroke, which isn't what you want.) Note that when you start typing a new key, its value appears to disappear -- this is because the dcList[key] refers to the new key name immediately. This would be somewhat confusing in a real UI, of course; you'd probably want to code different behavior into the createNewKey function (such copying the old value into the new key, or deleting the original key).

function recallCtrl($scope) {
    $scope.dcList = { 
        key: "value",
        abc: "aaaa",
        prop: "tadaa!"
    }
    
    $scope.createNewKey = function(k) {
      $scope.dcList[k]="";
    }

  }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="recallCtrl">
    <table class="table table-sm">
        <thead>
            <tr>
                <th>Key</th>
                <th>Value</th>
            </tr>
        </thead>
        <tr ng-repeat="(key, value) in dcList">
            <td>
                <input ng-model="key" ng-blur="createNewKey(key)"/>
            </td>
            <td>
                <input ng-model="dcList[key]"/>
            </td>
        </tr>
    </table>

    <pre>{{dcList | json}}</pre>
  </div>

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

3 Comments

Thanks for nice explanation :) I think I can adjust it for my needs.
key and value don't turn into primitives as you've suggested. You can verify this by adding {{key}} and {{value}} directly beside the <input> elements in the OP's original code. You will see that as you update the value in the <input> the corresponding key or value is updated as well.
@Lex, you're right; thank you for that. I'll correct the answer.
2

please test this code, change in the value corresponding to the key,

    angular.module('app', [])
  .controller('Controller', function($scope) {

    $scope.dcList = { 
        key: "value",
        abc: "aaaa",
        prop: "tadaa!"
    }
  })
   
<!DOCTYPE html>
<html>

<head>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>

</head>

<body ng-app="app">
  <div ng-controller="Controller">
      <table class="table table-sm">
        <thead>
            <tr>
                <td></td>
                <th>Key</th>
                <th>Value</th>
            </tr>
        </thead>
        <tr ng-repeat="(key, value) in dcList">
            <td>

            </td>
            <td>
                <input ng-model="key" disabled/>
            </td>
            <td>
                <input ng-model="dcList[key]" />
            </td>
        </tr>

    </table>

    <pre>{{dcList | json}}</pre>
  </div>
</body>

</html>

Here is the plunker

5 Comments

This only answers half the question.
yes, as changing the keys of the hash is not the correct thing, i disabled the keys for now, I am just waiting if the questioner want me to extend my answer.
There is no need for that, I already figured out why is it a bad idea, haven't done anything like that before so I didn't think of weird but expected UI behavior, thanks for explanation.
"changing the keys of the hash is not the correct thing" Eh? It's not the easy thing, but it's certainly reasonable for someone to want to know how to do that.
yes, that's correct. I never said you did the wrong thing. :)

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.