Github user doanduyhai commented on the pull request:

    https://github.com/apache/incubator-zeppelin/pull/740#issuecomment-190404497
  
    Hello @Leemoonsoo 
    
    > I think it's more clear to provide z.runParagraph() than z.angularBind() 
has flag of runParagraph.
    Having two different feature in a single function should be avoided.
    
    The reason why I add the `runParagraph` option for `z.angularBind()` is 
that it will be used in 80% of the time. Indeed, what's the point to bind an 
Angular variable if you don't **refresh** immediately the target paragraph for 
quick update ? I can't see any use-case where the user bind an Angular variable 
and do not click on the "Run" button on the target paragraph(s) or on the whole 
notebook itself.
    
    If we remove the `runParagraph` option, to achieve the same feature, we'll 
need:
    
    ```html
    
    <input type="text" ng-click="z.angularBind(....); z.runParagraph(...)" >
    ```
    
     or worst, the user should manually click on the target paragraph like in 
the screenshot, it's far from being user-friendly.
    
    > I think it can be improved by considering two perspective. The First one 
is easy of use. User need to repeat paragraph id to series of z.angularBind() 
again and again. e.g.
    
    I do agree with your on this point to some extent. Yes, it forces the user 
to do a manual copy and paste but once it's done, you don't need to update it 
again (we'll see this point below).
    
    But this issue also applies to `ZeppelinContext.runParagraph(String 
paragraphId)` if we had chosen to use the ZeppelinContext to run paragraphs in 
the back-end instead of front-end so I would say this issue is not really a new 
issue, it has always been there.
    
    > Second one is notebook portability, the code now depends on paragraph id 
and it's not portable anymore. If you export notebook and import notebook, the 
code will not work anymore unless user update all paragraph id in the code.
    
    
    
    You are absolutely right about this point. Indeed it's vey annoying that 
exporting and importing the same note make you loose the paragraph id. For this 
I see 2 solutions:
    
    1. first create the Angular `z` object from an HtmlElement as you suggest 
`var z = getZeppelinContext(htmlElement)`, the only problem is what is 
`htmlElement` ? How can we refer to a paragraph by its `htmlElement` ? I find 
it simpler to refer to a paragraph using its **id**     
    
    2. **I think we should fix the dynamic paragraph id and persist the 
paragraph id at the same time as the paragraph content**. As far as I can see, 
the paragraph id is generated using some timestamp plus a random part so there 
is very few chance of collision. Consequently it is possible to export a note 
with all the original paragraph ids and import them elsewhere
    
     WDYT ? 
    
    > front-end z.angularBind() call creates/updates angularObject into all 
interpreters binded.
    
    Allow me to disagree with this idea, if there are 10 paragraphs in the note 
with 10 different interpreters, it will create a lot of **pollution**. There is 
no reason that we push the Angular variable to many interpreters that are not 
used by the target paragraph(s).
    
    Another argument against binding the variable to all interpreters used by 
the note is because Angular variables are **persisted** in `note.json` file so 
we'll create a lot of data that will be exported/re-imported and not used ....
    
    > Could you explain advantage of having API in both front-end and back-end 
side ?
    
    Yes, this is part of the goal **Usability Improvement** in the roadmap.
    
    As an user, I want to be able to design a custom (with my own CSS etc ...) 
HTML form with my own controls (input text, drop down, calendar component, 
carrousel etc ...) and be able to push Angular variable to back-end.
    
    Without this PR, to do this, I'll need to write Scala code like 
    
    ```scala
    import org.apache.zeppelin.display.angular.paragraphscope._
    import AngularElem._
    
    <div>
      <div class="alert alert-info">This is an alert panel</div>
      <form class="form-inline">
        <div class="form-group">
          <input type="text" class="form-control"  placeholder="Input 
Text"></input>
        </div>
        <button type="submit" class="btn btn-primary">Click Me</button>
      </form>
    </div>.onEvent("ng-click", () => {
      //my callback routine
    }).display
    ```
    
     If I were a web developer using Zeppelin, **I don't understand why I am 
forced to use Scala and the Spark interpreter to produce AngularJS and HTML 
source code**... 
    
    Isn't it more natural to write **plain Javascript and AngularJS code** if 
you want to render HTML and bind AngularJS ?
    
     I have given many talks about Zeppelin since 6 months and everytime I 
build a beautiful pure HTML form using Bootstrap, people in the audience ask me 
why I have another paragraph with source code like this:
    
     ```scala
    
    z.angularBind(...)
    z.runParagraph(...)
     ```
    
     It seems so un-natural for users to have Scala code in a separate 
paragraph just to make the HTML form work. If we want to extend the user-base 
of Zeppelin, we need to provide user natural ways of creating Angular variable 
and not force them to use the Spark interpreter for that.
    
     There is also a demande on the user-mailing list recently to be able to 
update Angular variable from the front-end:
    
    
![image](https://cloud.githubusercontent.com/assets/1532977/13409353/55a4c728-df3b-11e5-877c-0c2ec387a4a8.png)
    
    
    
     So the demand for controlling Angular element is real, not just some fancy 
idea I have in mind.
    
    
     > Cons side, if user creates something that mixes both front-end side API 
and back-end side API at the same time, while front-end side(js in webbrowser) 
and back-end side (heterogeneous interpreters) runs asynchronously, i can 
easily imagine understanding behavior of those code will be really difficult.
    
      Totally agree that if one user try to bind AngularJS using the back-end 
API with ZeppelinContext or the new Angular API you introduce and the front-end 
API I propose, it will make things complicated. But again, it's the user 
responsibility to make clean code. You can never stop people from doing stupid 
things right ? 
    
    
    To conclude, what I propose is to make another PR, before we progress on 
this one, **to persist the paragraph Id with the note content** so that we 
don't have anymore export/import problem. 
    
     WDYT ?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---

Reply via email to