0

Have a requirement where the user should be able to display and update an XML using form fields.

To be able to display the XML and bind the XML elements to from fields, I did the following:

  1. Retrieve XML, convert to JSON (using xml2json) and put it in scope (name='domObject').
  2. Use angular directive on the HTML to get the domObject from scope and beatify it and display it (using vkbeautify)
  3. Also, on the same html, bind the form fields to the domObject from scope.

The binding from the domObject to the XML & form fields is working fine. But, when I make update the value in the field, the same is NOT reflected in the XML displayed (although the changes can be seen in the domObject) i.e 2 way binding is not happening when using the directive.

Please help.

Link to plunker here

Code Snippets

Main script:

var App = angular.module('myApp', []);
App.controller('myCtrl', function($scope, $http, $window) {

    $http.get("sample.xml")
        .then(function(response) {

        var x2js = new $window.X2JS();
        var jsonDocument = x2js.xml_str2json( response.data );
        $scope.domObject = jsonDocument;
        $scope.dataLoaded = true;
    });

})

App.directive('prettyprint', function($window) {
    return {
        restrict: 'C',
        replace: true,
        link: function postLink(scope, element, attrs) {
            var x2js = new $window.X2JS();
            var xmlString = x2js.json2xml_str(scope.domObject);
            element.text(vkbeautify.xml(xmlString, 4));
        }
    };
});

HTML Snippet:

<body ng-app="myApp">
    <section class="container">
                <div class="form-style-3" ng-controller="myCtrl">
                    <form novalidate ng-if="dataLoaded">
                        <fieldset><legend>Fields</legend>
                            Catalog Name
                            <input type="text" ng-model="domObject.catalog.name" />
                        </fieldset>
                    </form>
              <br />
          <div>
            <br />
                    XML Display:
                    <pre class="prettyprint lang-xml" ng-if="dataLoaded"></pre>

                    DOM Object: <br /><br />
                    {{domObject}}

                </div>
                </div>

    </section>
</body>

1 Answer 1

1

Your prettyprint directive takes scope.domObject initially and doesn't reflect to its changes.

One of the ways to do this is to setup a watcher like:

App.directive('prettyprint', function($window) {
    return {
        restrict: 'AC',
        replace: true,
        scope: {
          obj: '='
        },
        link: function postLink(scope, element, attrs) {
            scope.$watch('obj', function(val) {
              var x2js = new $window.X2JS();
              var xmlString = x2js.json2xml_str(val);
              element.text(vkbeautify.xml(xmlString, 4));
            }, true)
        }
    };
});

Here is working plnkr.

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

1 Comment

Thanks for the super quick response Stan. Works like a charm. Can't thank you enough. I tried with 'watch' on the 'domObject' directly from scope, but that obviously didn't work.

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.