AngularJS - adding new values to directive's isolated scope

I have a directive with isolated scope as following:

    application.directive("myDirective",function(){
        return {
            restrict: "A",
            scope: {myDirective:"="},
            link : function(scope) {
                console.log("My directive: ",scope.myDirective) // works fine
                scope.person={name:"John",surname:"Doe"}

                scope.hello=function(){
                    console.log("Hello world!")
                }
            }
        }
    })

Corresponding view:

<div my-directive='{testValue:3}'>
    Testvalue: {{myDirective}}<br/>
    Hello {{person}}
    <button ng-click="hello()">Say hello</button>
</div>

And it seems that i cannot use any of the fields declared in the scope. In view the "myDirecive" and "person" fields are blank and the scope's "hello" function is not executed when i press the button.

It works fine when i pass scope="true" to the directive but does not work in isolated scope.

Am i missing something here or maybe there is no way to introduce variables to the isolated scope of a directive?

UPDATE

Updated question presenting why i would rather not to use a static template. The effect i am trying to achieve is to make directive that allows to upload any html form getting the form initial data via rest/json. The whole process is rather complex and application specific therefore i cannot use any available form libraries. I present below the simplified version of the use case:

The updated directive

    application.directive("myForm",function(){
        return {
            restrict: "A",
            scope: {myForm:"="},
            link : function(scope) {
                console.log("Form parameters: ",scope.myForm) // works fine
                scope.formData=... // Get form initial data as JSON from server

                scope.submitForm=function(){
                   // Send scope.formData via REST to the server
                }
            }
        }
    })

The case when i would like to use this form. Of course i would like to use this directive many times with different forms.

<form my-form='{postUrl:'/myPostUrl',getFormDataUrl:'/url/to/some/json}'>
    <div>Form user: {{formData.userName}} {{formData.userSurname}}
    <input type="text" ng-model="formData.userAge" />
    <input type="text" ng-model="formData.userEmail" />
    <button ng-click="submitForm()">Submit</button>
</form>

I hope this explains why i cannot use one static html template for this scenario.

Maybe someone can explain why this is working with scope="true" and with an isolated scope i cannot access any scoped variables?

With Angular, directives either work with a template (or templateUrl) or with transcluded content.

If you're using a template, then the template has access to the isolate scope. So, if you put {{person}} in the template it would work as expected.

If you're using transcluded content - that is, the content that is a child of the node which has the directive applied to it - then, not only would you need to set transclude: true and specify where in the template the transcluded content goes - e.g. <div ng-transclude></div> to even see the content, you would also not get the results you expect, since the transcluded content has access to the same scope variables as the parent of the directive, and not to those available in the isolate scope of the directive.

Also, you should be aware that if you pass a non-assignable object to the directive's isolate scope with "=" - like you did with my-directive="{testValue: 3", then you can't make any changes to it (and, unfortunately, even to its properties even if they are scope variables).

So, to make your specific case work, do this:

application.directive("myDirective",function(){
  return {
    ...
    template: "Testvalue: {{myDirective}}<br/> " + 
              "Hello {{person}} " + 
              "<button ng-click="hello()">Say hello</button>";
  };
});

and the corresponding view:

where prop is set in the View controller to: $scope.prop = {testValue: 3};

You can always alter the default behavior of transcluded scope ( though I don't recommend it):

application.directive("myDirective",function(){
  return {
    tranclude: true,
    scope: {myDirective:"="},
    link : function(scope, element, attrs, ctrl, $transclude) {

      $transclude(scope, function(clone) {
        element.empty();
        element.append(clone);
      });

      scope.person={name:"John",surname:"Doe"};

      scope.hello=function(){
        console.log("Hello world!");
      };
    }
  };
});

See the docs: https://docs.angularjs.org/api/ng/service/$compile#transclusion-functions

Also take a look at ngTranslude source code: https://github.com/angular/angular.js/blob/master/src/ng/directive/ngTransclude.js