How to remove a child component with a delete button in the child itself

和自甴很熟 提交于 2019-12-29 01:45:12

问题


I have an email component (email-tag.html) that consist of a label, a select and a delete button element.

The email-tag.html component is hosted in its parent email-view-tag.html. email-view-tag contains an add-email-button that adds the email-tag element to the DOM each time it is clicked.

I need help in removing an added email-tag component when its delete-button is clicked. It is the compnoent that contains the delete-button that should be removed.

The two components are shown below:

email-tag.html

 <!DOCTYPE html>

<polymer-element name='email-tag'>
  <template>
   <style>

   .main-flex-container
   {
     display:flex;
     flex-flow:row wrap;
     align-content:flex-start;
   }

    .col
    {
      display:flex;
      flex-flow:column;
      align-content:flex-start;
      flex-grow:1;
    }
   </style>

   <div id='email' class='main-flex-container'>
      <section id='col1' class='col'>
        <input id=emailTxt
               type='text'
               list='_emails'
               value='{{webContact.homeEmail}}'>

        <datalist id='_emails'>
            <template repeat='{{email in emails}}'>
              <option value='{{email}}'>{{email}}</option>
            </template>
        </datalist>
      </section>

      <section id='col2' class='col'>
        <button id='delete-email-btn' type='button' on-click='{{deletePhone}}'>Delete</button>
      </section>
    </div>
   </template>

   <script type="application/dart">

    import 'package:polymer/polymer.dart' show CustomTag, PolymerElement;
    import 'dart:html' show Event, Node;

    @CustomTag( 'email-tag' )
    class EmailElement extends PolymerElement
    {
      //@observable
      EmailElement.created() : super.created();
      List<String> emails = [   '', 'Home', 'Personal', 'Private', 'Work', ];

      void deletePhone( Event e, var detail, Node target)
      {
        //shadowRoot.querySelector('#new-phone' ).remove();
        //print( 'Current row deleted' );
      }
    }
  </script>
</polymer-element>

email-view-tag.html

  <!DOCTYPE html>

  <link rel="import" href="email-tag.html">

  <polymer-element name='email-view-tag'>
    <template>
     <style>

     .main-flex-container
     {
       display:flex;
       flex-flow:row wrap;
       align-content:flex-start;
     }

      .col
      {
        display:flex;
        flex-flow:column;
        align-content:flex-start;
        flex-grow:1;
      }
     </style>

      <div id='email-view' class='main-flex-container'>
        <section id='row0'  >
          <button id='add-email-btn' type='button' on-click='{{addPhone}}'>Add Phone</button>
        </section >

        <section id='rows' class='col'>
       <!--    <epimss-phone-header-tag id='col1' class='col'></epimss-phone-header-tag> -->
          </section>
      </div>
     </template>

     <script type="application/dart">
      import 'package:polymer/polymer.dart' show CustomTag, PolymerElement;
      import 'dart:html' show Event, Node, Element;

      @CustomTag( 'email-view-tag' )
      class EmailViewElement extends PolymerElement
      {
        //@observable
        EmailViewElement.created() : super.created();

        void addPhone( Event e, var detail, Node target )
        {
          $[ 'rows' ].children.add( new Element.tag( 'email-tag' ) );
        }

        @override
        void attached() {
          super.attached();

          $[ 'add-email-btn' ].click();
        }
      }
    </script>
  </polymer-element>

The application does execute normally and clicking the add button does add the email component. The delete button does not work - it is here I am asking for help.

Thanks


回答1:


The child component, <email-tag> should not be in the business of deleting itself. Instead, it should delegate that responsibility to the the parent component, email-view-tag, by dispatching a custom event.

Here is the code for dispatching a custom event from deletePhone:

void deletePhone( Event e, var detail, Node target){
  dispatchEvent(new CustomEvent('notneeded'));
}

Then, in the parent, <custom-view>, change your code for adding <email-tag>s like so:

void addPhone( Event e, var detail, Node target ) {
  $['rows'].children.add( new Element.tag('email-tag'));
  $['rows'].on["notneeded"].listen((Event e) {
    (e.target as Element).remove();
  });
}

Also, I would change the name of deletePhone, since the method no longer deletes the record but merely informs the parent that it is not needed. Call it 'notNeeded' or something similar.




回答2:


EDIT @ShailenTuli is right about encapsulation should not be broken.

But also JS Polymer elements access the parent in their layout elements because it's still convenient in some scenarios.

This works now in PolymerDart too.

(this.parentNode as ShadowRoot).host

ORIGINAL

You can fire an event and make the email-view-tag listen to this tag and the event handler can remove the event target from it's childs.

  • I had a similar question a while ago: How to access parent model from polymer component

  • This was actually the question I wanted refer to
    How can I access the host of a custom element
    but the first one may be of some use too.

  • PolymerJS FAQ - When is the best time to access an element’s parent node?
    attached() currently still named enteredView() in Dart, but will be renamed probably soon.



来源:https://stackoverflow.com/questions/20406328/how-to-remove-a-child-component-with-a-delete-button-in-the-child-itself

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!