问:
Select based on another select using php Not working
Select based on another select using PHP not working only when a new row is added.

For demo visit here (See steps for demo)

There are two rows when the page is loaded, they are working as wanted. (Service option is as per item option)

Click on the Add Row button, one more row will be added

The newly inserted row is not working. (Service select is not giving any options, as first two gives)

What I tried:

```<code><?php require_once '../home.php' ?>
<?php

    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'], $_POST['id'] ) && $_POST['action']=='get_dependant_menu' ){
        ob_clean();

        $action=filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
        $id=filter_input( INPUT_POST, 'id', FILTER_SANITIZE_STRING );
        if( $action && $id && !is_nan( $id ) ){

            $stmt=$user_home->runQuery("SELECT * FROM service WHERE IRN=:irn ORDER BY Sr ASC ");
            $stmt->bindParam(':irn',$id);
            $stmt->execute();
            $stmtin=$user_home->runQuery("SELECT * FROM item WHERE IRN=:irn ORDER BY Sr ASC ");
            $stmtin->bindParam(':irn',$id);
            $stmtin->execute();
            $rowin=$stmtin->fetch( PDO::FETCH_ASSOC );

            if( $stmt->rowCount() > 0 ){
                echo "<option value='Select Service'>Select Service ({$rowin['Name']})</option>";
                 while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                    echo "<option value='{$row['SRN']}'>{$row['Name']}</option>";
                 }
            }
        }
        exit();
    }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type='text/javascript' charset='utf-8'>
            function ajax(m,u,p,c,o){
                var xhr=new XMLHttpRequest();
                xhr.onreadystatechange=function(){
                    if( xhr.readyState==4 && xhr.status==200 )c.call( this, xhr.response, o, xhr.getAllResponseHeaders() );
                };

                var params=[];
                for( var n in p )params.push(n+'='+p[n]);

                switch( m.toLowerCase() ){
                    case 'post': p=params.join('&'); break;
                    case 'get': u+='?'+params.join('&'); p=null; break;
                }

                xhr.open( m.toUpperCase(), u, true );
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send( p );
            }
            function createmenu(r,o,h){
                o.menu.innerHTML=r;
            }

            function bindEvents(){
                var oSelItem=document.querySelector('select[name="item1"]');
                var oSelService=document.querySelector('select[name="service1"]');
                oSelItem.onchange=function(e){

                    var method='post';
                    var url=location.href;
                    var params={
                        'action':'get_dependant_menu',
                        'id':this.options[ this.options.selectedIndex ].value
                    };
                    var opts={
                        menu:oSelService
                    };
                    ajax.call( this, method, url, params, createmenu, opts );
                }.bind( oSelItem );
            }
            document.addEventListener( 'DOMContentLoaded', bindEvents,false );
        </script>
</head>
<body>
<form method="post" action="invoice_form.php" id="item_sel">

    <table id="chiru_inv" class="table table-striped table-hover table-bordered table-responsive">
   <tr>
    <td colspan="3">
      <input type="text" name="customer" value="" placeholder="Customer Name">
    </td>
  </tr>
  <tr>
    <th>Item</th>
    <th>Service</th>
    <th>Qty</th>

  </tr>

    <tr>
      <td>
      <select name='item1' class='country'>
            <option value="Select Item">Select Item</option>
            <?php

                //$sql='select * from `item` order by `Sr` asc;';
                $stmt=$user_home->runQuery("SELECT * FROM item ORDER BY Sr ASC ");
                $stmt->execute();

                if( $stmt->rowCount() > 0 ){
                    while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                        echo "<option value='{$row['IRN']}'>{$row['Name']}</option>";
                    }
                }

            ?>
</select></td>

      <td><select class="country" name="service1">
</select></td>
<td><input type="text" name="qty1" value="" placeholder="Quantity"></td>
    </tr>
    <tr>
      <td>
      <select name='item2' class='country'>
            <option>Select Item</option>
            <?php

                $stmt=$user_home->runQuery("SELECT * FROM item ORDER BY Sr ASC ");
                $stmt->execute();

                if( $stmt->rowCount() > 0 ){
                    while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                        echo "<option value='{$row['IRN']}'>{$row['Name']}</option>";
                    }
                }

            ?>
</select></td>

      <td><select class="country" name="service2">
</select></td>
<td><input type="text" name="qty2" value="" placeholder="Quantity"></td>
    </tr>
    <tr>
        <td colspan="3"><button type="submit" name="btnsave" class="btn btn-default">
        <span class="glyphicon glyphicon-save"></span>   Save
        </button>
        </td>
    </tr>
</table>
    <input type="button" class="add-row" value="Add Row">
</form>
<div id="markup_model" class="hide">
  <table>
    <tr>
      <td>
        <select name="nameitem" class="country">
                    <option>Select Item</option>
                    <?php
                        $stmt=$user_home->runQuery("SELECT * FROM item ORDER BY Sr ASC ");
                        $stmt->execute();

                        if( $stmt->rowCount() > 0 ){
                            while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                                echo "<option value='{$row['IRN']}'>{$row['Name']}</option>";
                            }
                        }
                    ?>
                </select>
      </td>
      <td>
        <select class="country" name="namewhat"></select>
      </td>
      <td>
        <input type="text" name="nameqty" value="" placeholder="Quantity" />
      </td>
    </tr>
  </table>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
  var cont = 3
  var qty = "qty"
  var item = "item"
  var what = "service"

  $(".add-row").click(function() {
    var nameqty = qty + cont;
    var nameitem = item + cont;
    var namewhat = what + cont;

    var markup = $('#markup_model tbody');

    $(markup).find('.country:eq(0)').attr('name', nameitem);
    $(markup).find('.country:eq(1)').attr('name', namewhat);
    $(markup).find('input').attr('name', nameqty);

    $(markup.html()).insertBefore($('button[type="submit"]').closest("tr"));

    cont++;
  });
});
</script>
<script type='text/javascript' charset='utf-8'>
            function ajax(m,u,p,c,o){
                var xhr=new XMLHttpRequest();
                xhr.onreadystatechange=function(){
                    if( xhr.readyState==4 && xhr.status==200 )c.call( this, xhr.response, o, xhr.getAllResponseHeaders() );
                };

                var params=[];
                for( var n in p )params.push(n+'='+p[n]);

                switch( m.toLowerCase() ){
                    case 'post': p=params.join('&'); break;
                    case 'get': u+='?'+params.join('&'); p=null; break;
                }

                xhr.open( m.toUpperCase(), u, true );
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send( p );
            }
            function createmenu(r,o,h){
                o.menu.innerHTML=r;
            }

            function bindEvents(){
                var oSelItem2=document.querySelector('select[name="item2"]');
                var oSelService2=document.querySelector('select[name="service2"]');
                oSelItem2.onchange=function(e){

                    var method='post';
                    var url=location.href;
                    var params={
                        'action':'get_dependant_menu',
                        'id':this.options[ this.options.selectedIndex ].value
                    };
                    var opts={
                        menu:oSelService2
                    };
                    ajax.call( this, method, url, params, createmenu, opts );
                }.bind( oSelItem2 );
            }
            document.addEventListener( 'DOMContentLoaded', bindEvents,false );
        </script>
        <script type='text/javascript' charset='utf-8'>
            function ajax(m,u,p,c,o){
                var xhr=new XMLHttpRequest();
                xhr.onreadystatechange=function(){
                    if( xhr.readyState==4 && xhr.status==200 )c.call( this, xhr.response, o, xhr.getAllResponseHeaders() );
                };

                var params=[];
                for( var n in p )params.push(n+'='+p[n]);

                switch( m.toLowerCase() ){
                    case 'post': p=params.join('&'); break;
                    case 'get': u+='?'+params.join('&'); p=null; break;
                }

                xhr.open( m.toUpperCase(), u, true );
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send( p );
            }
            function createmenu(r,o,h){
                o.menu.innerHTML=r;
            }

            function bindEvents(){
                var oSelItem3=document.querySelector('select[name="item3"]');
                var oSelService3=document.querySelector('select[name="service3"]');
                oSelItem3.onchange=function(e){

                    var method='post';
                    var url=location.href;
                    var params={
                        'action':'get_dependant_menu',
                        'id':this.options[ this.options.selectedIndex ].value
                    };
                    var opts={
                        menu:oSelService3
                    };
                    ajax.call( this, method, url, params, createmenu, opts );
                }.bind( oSelItem3 );
            }
            document.addEventListener( 'DOMContentLoaded', bindEvents,false );
        </script>

</body>
</html>
</code>```

Body:
Select based on another select using PHP not working only when a new row is added.

For demo visit here (See steps for demo)

There are two rows when the page is loaded, they are working as wanted. (Service option is as per item option)

Click on the Add Row button, one more row will be added

The newly inserted row is not working. (Service select is not giving any options, as first two gives)

What I tried:

<?php require_once '../home.php' ?>
<?php

    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'], $_POST['id'] ) && $_POST['action']=='get_dependant_menu' ){
        ob_clean();

        $action=filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
        $id=filter_input( INPUT_POST, 'id', FILTER_SANITIZE_STRING );
        if( $action && $id && !is_nan( $id ) ){

            $stmt=$user_home->runQuery("SELECT * FROM service WHERE IRN=:irn ORDER BY Sr ASC ");
            $stmt->bindParam(':irn',$id);
            $stmt->execute();
            $stmtin=$user_home->runQuery("SELECT * FROM item WHERE IRN=:irn ORDER BY Sr ASC ");
            $stmtin->bindParam(':irn',$id);
            $stmtin->execute();
            $rowin=$stmtin->fetch( PDO::FETCH_ASSOC );

            if( $stmt->rowCount() > 0 ){
                echo "<option value='Select Service'>Select Service ({$rowin['Name']})</option>";
                 while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                    echo "<option value='{$row['SRN']}'>{$row['Name']}</option>";
                 }
            }
        }
        exit();
    }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<form method="post" action="invoice_form.php" id="item_sel">

      <input type="text" name="customer" value="" placeholder="Customer Name">

    Item
    Service
    Qty

      <select name='item1' class='country'>
            <option value="Select Item">Select Item</option>
            <?php

                //$sql='select * from `item` order by `Sr` asc;';
                $stmt=$user_home->runQuery("SELECT * FROM item ORDER BY Sr ASC ");
                $stmt->execute();

                if( $stmt->rowCount() > 0 ){
                    while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                        echo "<option value='{$row['IRN']}'>{$row['Name']}</option>";
                    }
                }

            ?>
</select>

      <select class="country" name="service1">
</select>
<input type="text" name="qty1" value="" placeholder="Quantity">

      <select name='item2' class='country'>
            <option>Select Item</option>
            <?php

                $stmt=$user_home->runQuery("SELECT * FROM item ORDER BY Sr ASC ");
                $stmt->execute();

                if( $stmt->rowCount() > 0 ){
                    while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                        echo "<option value='{$row['IRN']}'>{$row['Name']}</option>";
                    }
                }

            ?>
</select>

      <select class="country" name="service2">
</select>
<input type="text" name="qty2" value="" placeholder="Quantity">

        <button type="submit" name="btnsave" class="btn btn-default">
           Save
        </button>

    <input type="button" class="add-row" value="Add Row">
</form>

        <select name="nameitem" class="country">
                    <option>Select Item</option>
                    <?php
                        $stmt=$user_home->runQuery("SELECT * FROM item ORDER BY Sr ASC ");
                        $stmt->execute();

                        if( $stmt->rowCount() > 0 ){
                            while( $row=$stmt->fetch( PDO::FETCH_ASSOC ) ){
                                echo "<option value='{$row['IRN']}'>{$row['Name']}</option>";
                            }
                        }
                    ?>
                </select>

        <select class="country" name="namewhat"></select>

        <input type="text" name="nameqty" value="" placeholder="Quantity" />

Body:
In your code above you are running the same query twice which I presume is a copy/paste mistake?

What follows is based upon previous question and help already offered.

mysql> describe irn_item;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| irn   | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(50)      | YES  |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+

mysql> select * from irn_item;
+-----+------------+
| irn | name       |
+-----+------------+
|   1 | Shirt      |
|   2 | Trousers   |
|   3 | Jacket     |
|   4 | Socks      |
|   5 | Underpants |
|   6 | Hat        |
+-----+------------+

mysql> describe irn_service;
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| srn         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| irn         | int(10) unsigned | NO   | MUL | 1       |                |
| instruction | varchar(50)      | NO   |     | 1       |                |
+-------------+------------------+------+-----+---------+----------------+

mysql> select * from irn_service;
+-----+-----+-----------------------+
| srn | irn | instruction           |
+-----+-----+-----------------------+
|   1 |   2 | Iron                  |
|   2 |   1 | Dry Clean Only        |
|   3 |   3 | Hi-Pressure dry clean |
|   4 |   4 | Steam Clean           |
|   5 |   5 | Decontaminate         |
|   6 |   6 | Waterproof            |
+-----+-----+-----------------------+

Without knowing the schema of the database I made up a quick example database based upon some of the columns seen in the sql in the original code. The code below uses mysqli rather than PDO simply because for my testing it is much quicker to write so please ignore the fact that it does not follow exactly. The important aspect that you are having troubles with, I believe, is that newly added rows do not copy the event handler which triggers the ajax request. I did make mention yesterday that when cloning nodes any event handlers assigned using addEventListener will NOT be copied/cloned - so to ensure that event handlers are copied/cloned you need to use inline event handlers ~ ie: <select onchange='evtselect(event)'>...</select>

<?php

    $dbhost =   'localhost';
    $dbuser =   'root';
    $dbpwd  =   'xxx';
    $dbname =   'xxx';
    $db =   new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );

    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'], $_POST['id'] ) && $_POST['action']=='get_dependant_menu' ){

        ob_clean();

        try{
            $id=filter_input( INPUT_POST, 'id', FILTER_SANITIZE_STRING );

            if( $id && !empty( $id ) ){

                $html=array();

                $sql='select `srn`,`instruction` from `irn_service` where `irn` = ? order by `srn` asc';
                $stmt=$db->prepare( $sql );

                if( $stmt ){
                    $stmt->bind_param( 's', $id );
                    $stmt->execute();
                    $stmt->store_result();
                    $stmt->bind_result( $srn, $instruction );

                    while( $stmt->fetch() ){
                        $html[]="<option value='{$srn}'>{$instruction}";
                    }
                    $stmt->close();
                }

                header('Content-Type: text/html');
                echo implode( PHP_EOL, $html );
            }
        }catch( Exception $e ){
            echo $e->getMessage();
        }
        exit();
    }
?>
<!doctype html>
<html>
    <head>
        <title>Dependent / Chained SELECT menus</title>
        <script>
            /* AJAX FUNCTION */
            function ajax(m,u,p,c,o){
                var xhr=new XMLHttpRequest();
                xhr.onreadystatechange=function(){
                    if( xhr.readyState==4 && xhr.status==200 )c.call( this, xhr.response, o, xhr.getAllResponseHeaders() );
                };

                var params=[];
                for( var n in p )params.push(n+'='+p[n]);

                switch( m.toLowerCase() ){
                    case 'post': p=params.join('&'); break;
                    case 'get': u+='?'+params.join('&'); p=null; break;
                }

                xhr.open( m.toUpperCase(), u, true );
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send( p );
            }

            /* AJAX CALLBACK */
            function createmenu(r,o,h){
                o.menu.innerHTML=r;
            }

            /* UTILITY TO FIND NEXT SIBLING ELEMENT NODE */
            function get_nextsibling(n){
                x=n.nextSibling;
                while ( x.nodeType!==1 ) x=x.nextSibling;
                return x;
            }

            /* INLINE EVENT HANDLER */
            function evtselect(e){
                try{
                    var el=e.target;
                    if( el.value=='null' || el.value==null )return false;

                    var method='post';
                    var url=location.href;
                    var params={
                        'action':'get_dependant_menu',
                        'id':el.value
                    };
                    var td=get_nextsibling( el.parentNode );
                    var oSelect=td.querySelector('select');

                    var opts={
                        menu:oSelect
                    };
                    ajax.call( this, method, url, params, createmenu, opts );
                }catch( err ){
                    console.log( err );
                }
            }

            function bindEvents(){

                var bttn=document.querySelector('input[name="add"]');
                var tbl=document.querySelector('form#item_sel > table');

                if( bttn && tbl ){
                    bttn.addEventListener('click',function(e){
                        /* get a reference to the first & last row, of class "item", in table */
                        var tr=tbl.querySelectorAll( 'tr.items' )[0];
                        var ref=tbl.querySelector( 'tr.save' );

                        /* Create a clone of the entire row - which includes the inline event handlers */
                        var clone=tr.cloneNode( true );

                        /* Insert the new row after the last row */
                        tr.parentNode.insertBefore( clone, ref );

                        /* Ensure that newly added "service" select menu is empty */
                        clone.querySelector('select[name="item[]"]').value='null';
                        clone.querySelector('select[name="service[]"]').innerHTML='';
                        clone.querySelector('input[name="qty[]"]').value='';

                    },{ capture:false, passive:true, once:false } );
                }
            }
            document.addEventListener( 'DOMContentLoaded', bindEvents, false );
        </script>
        <style type='text/css' charset='utf-8'>
            select {padding:1rem;width:300px;}
        </style>
    </head>
    <body>
        <h1>Chained select menus using basic ajax</h1>
        <form method='post' id='item_sel'>
            <table>
                <tr class='headers'>
                    <th scope='col'>Item</th>
                    <th scope='col'>Service</th>
                    <th scope='col'>Qty</th>
                </tr>
                <tr class='items'>
                    <td>
                        <select name='item' class='country' onchange='evtselect(event)'>
                            <option value=null>Please Select
                        <?php
                            $sql='select * from `irn_item` order by `irn`;';
                            $result=$db->query( $sql );
                            $html=array();
                            if( $result ){
                                while( $rs=$result->fetch_object() ){
                                    $html[]="<option value='{$rs->irn}'>{$rs->name}";
                                }
                                echo implode( PHP_EOL, $html );
                            }
                        ?>
                        </select>
                    </td>
                    <td><select name='service' class='country'></select></td>
                    <td><input type='number' name='qty' min=0 max=1000 /></td>
                </tr>
                <tr class='save'>
                    <td colspan='3'>
                        <button type='submit' name='btnsave' class='btn btn-default'>
                            <span class='glyphicon glyphicon-save'></span> &nbsp; Save
                        </button>
                    </td>
                </tr>
            </table>
            <input name='add' type='button' class='add-row' value='Add Row' />
        </form>
    </body>
</html>

With this code I took the trouble of renaming newly added elements - this is probably not strictly necessary as you could instead use array syntax for the element names - viz: <select name='item[]' onchange='evtselect(event)> or <input type='number' name='qty[]' /> etc then access the appropriate values in PHP in the usual manner. It should be mentioned that if you decide upon that approach (ie array syntax ) then you would need to look at the various selectors used in the javascript and edit the names appropriately.

I trust that with this new insight into the use of inline event handlers that you should be able to nail the problem you have - you can, with a little minor editing of this code, run it for yourself to see the application working correctly. You should edit the table names (irn_item -> item, irn_service -> service ) and add suitable db/pwd details... Good luck


来源: stackexchange

问:
From the server is there a way to know that my page is being loaded in an Iframe
I am using sammy.js in my webpage, and if someone uses this webpage in an IFrame (for IE), it will simply redirect the whole page to the location of the IFrame.So, I was thinking if there is a way to check if my page is being requested by an IFrame.If that is the case, then I can simply disable sammy(change lines that play with top.location).

I was thinking that a browser would be sending a few more headers , when a page is loaded in an IFrame.

答:
You can do this using javascript with the following code:

```<code>if (window!=window.top) { /* I'm in a frame! */ }
</code>```

To the best of my knowledge, though, there is no way to find this out serverside, as the browser merely sends an http request like it always would.  You can try just dumping all of the headers to see if there's any discernible difference, but I really doubt it.

ContentLicense: CC BY-SA 2.5

Body:
You can do this using javascript with the following code:

if (window!=window.top) { /* I'm in a frame! */ }

To the best of my knowledge, though, there is no way to find this out serverside, as the browser merely sends an http request like it always would.  You can try just dumping all of the headers to see if there's any discernible difference, but I really doubt it.


问:
How to define properties in spring dsl in apache camel
How can I define the properties with Spring DSL in Apache Camel ? With Blueprint you can do it via:

```<code> <cm:property-placeholder persistent-id="org.apache.servicemix.examples.cxf.receive" update-strategy="reload">
        <cm:default-properties>
            <cm:property name="CXFserver" value="http://localhost:8989/"/>
            <cm:property name="service" value="soap" />
        </cm:default-properties>
    </cm:property-placeholder>

    <camelcxf:cxfEndpoint id="personService"
                          address="${CXFserver}${service}"
                          serviceClass="org.apache.servicemix.examples.camel.soap.PersonService"
                          />
</code>```

But with Spring DSL what should I do like the example above? Below my camel-cxf.xml file:

```<code><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://camel.apache.org/schema/cxf"
    xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://camel.apache.org/schema/cxf
         http://camel.apache.org/schema/cxf/camel-cxf.xsd">

    <!-- setting up a Camel CXF web-service -->
    <cxf:cxfEndpoint id="orderEndpoint"
        loggingFeatureEnabled="true" address="http://localhost:9000/order/"
        serviceClass="com.aa.kk.service.OrderService" />

</beans>
</code>```

答: See the documentation: http://camel.apache.org/using-propertyplaceholder.html in the section configuring in spring xml

ContentLicense: CC BY-SA 3.0

Body:
How can I define the properties with Spring DSL in Apache Camel ? With Blueprint you can do it via:

 <cm:property-placeholder persistent-id="org.apache.servicemix.examples.cxf.receive" update-strategy="reload">
        <cm:default-properties>
            <cm:property name="CXFserver" value="http://localhost:8989/"/>
            <cm:property name="service" value="soap" />
        </cm:default-properties>
    </cm:property-placeholder>

    <camelcxf:cxfEndpoint id="personService"
                          address="${CXFserver}${service}"
                          serviceClass="org.apache.servicemix.examples.camel.soap.PersonService"
                          />

But with Spring DSL what should I do like the example above? Below my camel-cxf.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://camel.apache.org/schema/cxf"
    xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://camel.apache.org/schema/cxf
         http://camel.apache.org/schema/cxf/camel-cxf.xsd">

    <cxf:cxfEndpoint id="orderEndpoint"
        loggingFeatureEnabled="true" address="http://localhost:9000/order/"
        serviceClass="com.aa.kk.service.OrderService" />

</beans>


问:
Android AudioManager abandonAudioFocus not helped other apps to playmusic
Working on Voip call app, Issue is start native music player and play song, and opened my app made call after call music player doesn't resume playing by getting focus. What could be the issue, Thanks in advance.

Note : Native call app doing well in this case

AudioFocusChangeListener :

```<code>AudioManager.OnAudioFocusChangeListener mListener
    = new AudioManager.OnAudioFocusChangeListener() {
   @Override
   public void onAudioFocusChange(int i) {
      MLog.e(TAG, "onAudioFocusChange(" + i + ")");
   }
};
 am.requestAudioFocus(mListener, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
</code>```

After Use trying to give focus for other apps to resume other app work:

```<code>AudioManager am = getAudioManager();
am.abandonAudioFocus(mListener);
</code>```

答:
I am not sure whether i got your question correctly or not , but let me explain.

Your working on a Voip call app and in your case when ever user playing some music and try to make a call from app , the native player music has to be pause and again after call is completed it has to resume the playback.

Are you making calls with the use of TelephonyManager ? Then you can look at this solution where you can listen for changes in the call state using a PhoneStateListener. You can register the listener in the TelephonyManager:

If so, When ever your making any call from your Voip call app, simply check for the isMusicActive in the AudioManager. It will give the active music playing in the phone  including custom apps.

isMusicActive()  Checks whether any music is active. from  docs

```<code> AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

if(mAudioManager.isMusicActive()) {
    Intent i = new Intent(SERVICECMD);
    i.putExtra(CMDNAME , CMDPAUSE );
    sendBroadcast(i);
}
</code>```

Here if MusicActive then simply pass it and do your calling. Once your done with your calling start / pause the Music player again, It will works for all the players not only for Default music player.

Control the default music player of android with these are the commands

```<code>public static final String CMDTOGGLEPAUSE = "togglepause";
 public static final String CMDPLAY = "play";
 public static final String CMDPAUSE = "pause";
 public static final String CMDPREVIOUS = "previous";
 public static final String CMDNEXT = "next";
 public static final String SERVICECMD = "com.android.music.musicservicecommand";
 public static final String CMDNAME = "command";
 public static final String CMDSTOP = "stop";
</code>```

In your case, before making the voip call from your app, check any active music is there or not like this ,

```<code> private boolean isSomethingPlaying;

  AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

if(mAudioManager.isMusicActive()) {

   // some music is playing, so make it pause and save the flag for further usage.

   isSomethingPlaying = true;

    Intent i = new Intent(SERVICECMD);
    i.putExtra(CMDNAME , CMDPAUSE );
    sendBroadcast(i);
}
</code>```

After your call is completed , then in that function check whether u made any music pause by using broadcast with the flag.

```<code>if(isSomethingPlaying)
{
  // before our call some music is playing. so make it play again.
    isSomethingPlaying = false;
   Intent i = new Intent(SERVICECMD);
        i.putExtra(CMDNAME , CMDPLAY);
        sendBroadcast(i);
}
</code>```

Body:
Working on Voip call app, Issue is start native music player and play song, and opened my app made call after call music player doesn't resume playing by getting focus. What could be the issue, Thanks in advance.

Note : Native call app doing well in this case

AudioFocusChangeListener :

AudioManager.OnAudioFocusChangeListener mListener
    = new AudioManager.OnAudioFocusChangeListener() {
   @Override
   public void onAudioFocusChange(int i) {
      MLog.e(TAG, "onAudioFocusChange(" + i + ")");
   }
};
 am.requestAudioFocus(mListener, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);

After Use trying to give focus for other apps to resume other app work:

AudioManager am = getAudioManager();
am.abandonAudioFocus(mListener);

Body:
I am not sure whether i got your question correctly or not , but let me explain.

Your working on a Voip call app and in your case when ever user playing some music and try to make a call from app , the native player music has to be pause and again after call is completed it has to resume the playback.

Are you making calls with the use of TelephonyManager ? Then you can look at this solution where you can listen for changes in the call state using a PhoneStateListener. You can register the listener in the TelephonyManager:

If so, When ever your making any call from your Voip call app, simply check for the isMusicActive in the AudioManager. It will give the active music playing in the phone  including custom apps.

isMusicActive()  Checks whether any music is active. from  docs

 AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

if(mAudioManager.isMusicActive()) {
    Intent i = new Intent(SERVICECMD);
    i.putExtra(CMDNAME , CMDPAUSE );
    sendBroadcast(i);
}

Here if MusicActive then simply pass it and do your calling. Once your done with your calling start / pause the Music player again, It will works for all the players not only for Default music player.

Control the default music player of android with these are the commands

public static final String CMDTOGGLEPAUSE = "togglepause";
 public static final String CMDPLAY = "play";
 public static final String CMDPAUSE = "pause";
 public static final String CMDPREVIOUS = "previous";
 public static final String CMDNEXT = "next";
 public static final String SERVICECMD = "com.android.music.musicservicecommand";
 public static final String CMDNAME = "command";
 public static final String CMDSTOP = "stop";

In your case, before making the voip call from your app, check any active music is there or not like this ,

 private boolean isSomethingPlaying;

  AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

if(mAudioManager.isMusicActive()) {

   // some music is playing, so make it pause and save the flag for further usage.

   isSomethingPlaying = true;

    Intent i = new Intent(SERVICECMD);
    i.putExtra(CMDNAME , CMDPAUSE );
    sendBroadcast(i);
}

After your call is completed , then in that function check whether u made any music pause by using broadcast with the flag.

if(isSomethingPlaying)
{
  // before our call some music is playing. so make it play again.
    isSomethingPlaying = false;
   Intent i = new Intent(SERVICECMD);
        i.putExtra(CMDNAME , CMDPLAY);
        sendBroadcast(i);
}


问:
Android Tab layout: Wrap tab indicator width with respect to tab title
Is there any way to wrap tab indicator width with respect to tab title ?

答:
You can do it using styles.

In the layout xml:

```<code><android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        style="@style/AppTabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</code>```

in the styles.xml:

```<code><style name="AppTabLayout" parent="Widget.Design.TabLayout">
    <item name="android:layout_marginLeft">40dp</item>
    <item name="android:layout_marginRight">40dp</item>
</style>
</code>```

Body:
You can do it using styles.

In the layout xml:

<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        style="@style/AppTabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

in the styles.xml:

<style name="AppTabLayout" parent="Widget.Design.TabLayout">
    <item name="android:layout_marginLeft">40dp</item>
    <item name="android:layout_marginRight">40dp</item>
</style>


问:
Add string resources instead of static data
I am trying to add some string resources to replace Content string but i cannot seem to access them because its a static class. How do i add items to DummyItem from a non static context?

I edited to add a custom context class i seen on another post.
It works now but the custom context class throws a warning - Do not place Android context classes in static fields; this is a memory leak.

Is this actually a memory leak? How? and can i resolve it?

// Custom Context Class

```<code>public class MyCustomContext extends Application {

    private static Context context;

    public void onCreate() {
        super.onCreate();
        MyCustomContext.context = getApplicationContext();
    }

    public static Context getAppContext() {
        return MyCustomContext.context;
    }
}
</code>```

// Dummy Content Class

```<code>public class DummyContent {

    public static final List<DummyItem> ITEMS = new ArrayList<>();

    public static final Map<String, DummyItem> ITEM_MAP = new HashMap<>(5);

    static {
        addItem(new DummyItem("1", R.drawable.p1, "Item #1", "Author A", res.MyCustomContext.getAppContext().getString(R.string.ContentA));
        addItem(new DummyItem("2", R.drawable.p2, "Item #2", "Author B", res.MyCustomContext.getAppContext().getString(R.string.ContentB));
        addItem(new DummyItem("3", R.drawable.p3, "Item #3", "Author C", res.MyCustomContext.getAppContext().getString(R.string.ContentC)));
    }

    private static void addItem(DummyItem item) {
        ITEMS.add(item);
        ITEM_MAP.put(item.id, item);
    }

    public static class DummyItem {
        public final String id;
        public final int photoId;
        public final String title;
        public final String author;
        public final String content;

        public DummyItem(String id, int photoId, String title, String author, String content) {
            this.id = id;
            this.photoId = photoId;
            this.title = title;
            this.author = author;
            this.content = content;
        }
    }
}
</code>```

// List Fragment

```<code>import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ListFragment;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.BitmapImageViewTarget;

import com.app.test.R;
import com.app.test.DummyContent;

/**
 * Shows a list of all available quotes.
 */
public class PortfolioListFragment extends ListFragment {

    private Callback callback = dummyCallback;

    /**
     * A callback interface. Called whenever a item has been selected.
     */
    public interface Callback {
        void onItemSelected(String id);
    }

    /**
     * A dummy no-op implementation of the Callback interface. Only used when no active Activity is present.
     */
    private static final Callback dummyCallback = new Callback() {
        @Override
        public void onItemSelected(String id) {
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new MyListAdapter());
        setHasOptionsMenu(true);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        // notify callback about the selected list item
        callback.onItemSelected(DummyContent.ITEMS.get(position).id);
    }

    /**
     * onAttach(Context) is not called on pre API 23 versions of Android.
     * onAttach(Activity) is deprecated but still necessary on older devices.
     */
    @TargetApi(23)
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        onAttachToContext(context);
    }

    /**
     * Deprecated on API 23 but still necessary for pre API 23 devices.
     */
    @SuppressWarnings("deprecation")
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            onAttachToContext(activity);
        }
    }

    /**
     * Called when the fragment attaches to the context
     */
    protected void onAttachToContext(Context context) {
        if (!(context instanceof Callback)) {
            throw new IllegalStateException("Activity must implement callback interface.");
        }

        callback = (Callback) context;
    }

    private class MyListAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return DummyContent.ITEMS.size();
        }

        @Override
        public Object getItem(int position) {
            return DummyContent.ITEMS.get(position);
        }

        @Override
        public long getItemId(int position) {
            return DummyContent.ITEMS.get(position).id.hashCode();
        }

        @Override
        public View getView(int position, View convertView, ViewGroup container) {
            if (convertView == null) {
                convertView = LayoutInflater.from(getActivity()).inflate(R.layout.list_item_article, container, false);
            }

            final DummyContent.DummyItem item = (DummyContent.DummyItem) getItem(position);
            ((TextView) convertView.findViewById(R.id.article_title)).setText(item.title);
            ((TextView) convertView.findViewById(R.id.article_subtitle)).setText(item.author);
            final ImageView img = (ImageView) convertView.findViewById(R.id.thumbnail);
            Glide.with(getActivity()).load(item.photoId).asBitmap().into(new BitmapImageViewTarget(img) {
                @Override
                protected void setResource(Bitmap resource) {
                    RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(getActivity().getResources(), resource);
                    circularBitmapDrawable.setCircular(true);
                    img.setImageDrawable(circularBitmapDrawable);
                }
            });

            return convertView;
        }
    }

    public PortfolioListFragment() {
    }
}
</code>```

答:
Check below code . You can pass a Context when Calling this Class from the activity and than you can acess the  String resources .

```<code>public class DummyContent {

    /**
     * An array of sample items.
     */
    private  Context context ;
    public DummyContent(Context context){
        this.context = context ;
        addStaticItem();
    }

    public static  List<DummyItem> ITEMS = new ArrayList<>();

    /**
     * A map of sample items. Key: sample ID; Value: Item.
     */
    public static  Map<String, DummyItem> ITEM_MAP = new HashMap<>(5);

     public void addStaticItem(){
         addItem(new DummyItem("1", R.drawable.ic_launcher, "Item #1", "Author A", "Content A"));
         addItem(new DummyItem("2", R.drawable.ic_launcher, "Item #2", "Author B","Content B"));
         addItem(new DummyItem("3", R.drawable.ic_launcher, "Item #3", "Author C", context.getResources().getString(R.string.text_ok) ));
     }

    private void addItem(DummyItem item) {
        ITEMS.add(item);
        ITEM_MAP.put(item.id, item);
    }

    public  class DummyItem {
        public  String id;
        public  int photoId;
        public  String title;
        public  String author;
        public  String content;

        public DummyItem(String id, int photoId, String title, String author, String content) {
            this.id = id;
            this.photoId = photoId;
            this.title = title;
            this.author = author;
            this.content = content;
        }
    }
}
</code>```

Below is your PortfolioListFragment class :

```<code>public class PortfolioListFragment extends ListFragment {

    private Callback callback = dummyCallback;

    /**
     * A callback interface. Called whenever a item has been selected.
     */
    public interface Callback {
        void onItemSelected(String id);
    }

    /**
     * A dummy no-op implementation of the Callback interface. Only used when no active Activity is present.
     */
    private static final Callback dummyCallback = new Callback() {
        @Override
        public void onItemSelected(String id) {
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DummyContent dummyContent = new DummyContent(getContext());
        setListAdapter(new MyListAdapter());
        setHasOptionsMenu(true);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        // notify callback about the selected list item
        callback.onItemSelected(DummyContent.ITEMS.get(position).id);
    }

    /**
     * onAttach(Context) is not called on pre API 23 versions of Android.
     * onAttach(Activity) is deprecated but still necessary on older devices.
     */
    @TargetApi(23)
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        onAttachToContext(context);
    }

    /**
     * Deprecated on API 23 but still necessary for pre API 23 devices.
     */
    @SuppressWarnings("deprecation")
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            onAttachToContext(activity);
        }
    }

    /**
     * Called when the fragment attaches to the context
     */
    protected void onAttachToContext(Context context) {
        if (!(context instanceof Callback)) {
            throw new IllegalStateException("Activity must implement callback interface.");
        }

        callback = (Callback) context;
    }

    private class MyListAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return DummyContent.ITEMS.size();
        }

        @Override
        public Object getItem(int position) {
            return DummyContent.ITEMS.get(position);
        }

        @Override
        public long getItemId(int position) {
            return DummyContent.ITEMS.get(position).id.hashCode();
        }

        @Override
        public View getView(int position, View convertView, ViewGroup container) {
            if (convertView == null) {
                convertView = LayoutInflater.from(getActivity()).inflate(R.layout.list_item_article, container, false);
            }

            final DummyContent.DummyItem item = (DummyContent.DummyItem) getItem(position);
            ((TextView) convertView.findViewById(R.id.article_title)).setText(item.title);
            ((TextView) convertView.findViewById(R.id.article_subtitle)).setText(item.author);
            final ImageView img = (ImageView) convertView.findViewById(R.id.thumbnail);
            Glide.with(getActivity()).load(item.photoId).asBitmap().into(new BitmapImageViewTarget(img) {
                @Override
                protected void setResource(Bitmap resource) {
                    RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(getActivity().getResources(), resource);
                    circularBitmapDrawable.setCircular(true);
                    img.setImageDrawable(circularBitmapDrawable);
                }
            });

            return convertView;
        }
    }

    public PortfolioListFragment() {
    }
}
</code>```

Body:
I am trying to add some string resources to replace Content string but i cannot seem to access them because its a static class. How do i add items to DummyItem from a non static context?

I edited to add a custom context class i seen on another post.
It works now but the custom context class throws a warning - Do not place Android context classes in static fields; this is a memory leak.

Is this actually a memory leak? How? and can i resolve it?

// Custom Context Class

public class MyCustomContext extends Application {

    private static Context context;

    public void onCreate() {
        super.onCreate();
        MyCustomContext.context = getApplicationContext();
    }

    public static Context getAppContext() {
        return MyCustomContext.context;
    }
}

// Dummy Content Class

public class DummyContent {

    public static final List<DummyItem> ITEMS = new ArrayList<>();

    public static final Map<String, DummyItem> ITEM_MAP = new HashMap<>(5);

    static {
        addItem(new DummyItem("1", R.drawable.p1, "Item #1", "Author A", res.MyCustomContext.getAppContext().getString(R.string.ContentA));
        addItem(new DummyItem("2", R.drawable.p2, "Item #2", "Author B", res.MyCustomContext.getAppContext().getString(R.string.ContentB));
        addItem(new DummyItem("3", R.drawable.p3, "Item #3", "Author C", res.MyCustomContext.getAppContext().getString(R.string.ContentC)));
    }

    private static void addItem(DummyItem item) {
        ITEMS.add(item);
        ITEM_MAP.put(item.id, item);
    }

    public static class DummyItem {
        public final String id;
        public final int photoId;
        public final String title;
        public final String author;
        public final String content;

        public DummyItem(String id, int photoId, String title, String author, String content) {
            this.id = id;
            this.photoId = photoId;
            this.title = title;
            this.author = author;
            this.content = content;
        }
    }
}

// List Fragment

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ListFragment;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.BitmapImageViewTarget;

import com.app.test.R;
import com.app.test.DummyContent;

/**
 * Shows a list of all available quotes.
 */
public class PortfolioListFragment extends ListFragment {

    private Callback callback = dummyCallback;

    /**
     * A callback interface. Called whenever a item has been selected.
     */
    public interface Callback {
        void onItemSelected(String id);
    }

    /**
     * A dummy no-op implementation of the Callback interface. Only used when no active Activity is present.
     */
    private static final Callback dummyCallback = new Callback() {
        @Override
        public void onItemSelected(String id) {
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new MyListAdapter());
        setHasOptionsMenu(true);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        // notify callback about the selected list item
        callback.onItemSelected(DummyContent.ITEMS.get(position).id);
    }

    /**
     * onAttach(Context) is not called on pre API 23 versions of Android.
     * onAttach(Activity) is deprecated but still necessary on older devices.
     */
    @TargetApi(23)
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        onAttachToContext(context);
    }

    /**
     * Deprecated on API 23 but still necessary for pre API 23 devices.
     */
    @SuppressWarnings("deprecation")
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            onAttachToContext(activity);
        }
    }

    /**
     * Called when the fragment attaches to the context
     */
    protected void onAttachToContext(Context context) {
        if (!(context instanceof Callback)) {
            throw new IllegalStateException("Activity must implement callback interface.");
        }

        callback = (Callback) context;
    }

    private class MyListAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return DummyContent.ITEMS.size();
        }

        @Override
        public Object getItem(int position) {
            return DummyContent.ITEMS.get(position);
        }

        @Override
        public long getItemId(int position) {
            return DummyContent.ITEMS.get(position).id.hashCode();
        }

        @Override
        public View getView(int position, View convertView, ViewGroup container) {
            if (convertView == null) {
                convertView = LayoutInflater.from(getActivity()).inflate(R.layout.list_item_article, container, false);
            }

            final DummyContent.DummyItem item = (DummyContent.DummyItem) getItem(position);
            ((TextView) convertView.findViewById(R.id.article_title)).setText(item.title);
            ((TextView) convertView.findViewById(R.id.article_subtitle)).setText(item.author);
            final ImageView img = (ImageView) convertView.findViewById(R.id.thumbnail);
            Glide.with(getActivity()).load(item.photoId).asBitmap().into(new BitmapImageViewTarget(img) {
                @Override
                protected void setResource(Bitmap resource) {
                    RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(getActivity().getResources(), resource);
                    circularBitmapDrawable.setCircular(true);
                    img.setImageDrawable(circularBitmapDrawable);
                }
            });

            return convertView;
        }
    }

    public PortfolioListFragment() {
    }
}

Body:
Check below code . You can pass a Context when Calling this Class from the activity and than you can acess the  String resources .

public class DummyContent {

    /**
     * An array of sample items.
     */
    private  Context context ;
    public DummyContent(Context context){
        this.context = context ;
        addStaticItem();
    }

    public static  List<DummyItem> ITEMS = new ArrayList<>();

    /**
     * A map of sample items. Key: sample ID; Value: Item.
     */
    public static  Map<String, DummyItem> ITEM_MAP = new HashMap<>(5);

     public void addStaticItem(){
         addItem(new DummyItem("1", R.drawable.ic_launcher, "Item #1", "Author A", "Content A"));
         addItem(new DummyItem("2", R.drawable.ic_launcher, "Item #2", "Author B","Content B"));
         addItem(new DummyItem("3", R.drawable.ic_launcher, "Item #3", "Author C", context.getResources().getString(R.string.text_ok) ));
     }

    private void addItem(DummyItem item) {
        ITEMS.add(item);
        ITEM_MAP.put(item.id, item);
    }

    public  class DummyItem {
        public  String id;
        public  int photoId;
        public  String title;
        public  String author;
        public  String content;

        public DummyItem(String id, int photoId, String title, String author, String content) {
            this.id = id;
            this.photoId = photoId;
            this.title = title;
            this.author = author;
            this.content = content;
        }
    }
}

Below is your PortfolioListFragment class :

public class PortfolioListFragment extends ListFragment {

    private Callback callback = dummyCallback;

    /**
     * A callback interface. Called whenever a item has been selected.
     */
    public interface Callback {
        void onItemSelected(String id);
    }

    /**
     * A dummy no-op implementation of the Callback interface. Only used when no active Activity is present.
     */
    private static final Callback dummyCallback = new Callback() {
        @Override
        public void onItemSelected(String id) {
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DummyContent dummyContent = new DummyContent(getContext());
        setListAdapter(new MyListAdapter());
        setHasOptionsMenu(true);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        // notify callback about the selected list item
        callback.onItemSelected(DummyContent.ITEMS.get(position).id);
    }

    /**
     * onAttach(Context) is not called on pre API 23 versions of Android.
     * onAttach(Activity) is deprecated but still necessary on older devices.
     */
    @TargetApi(23)
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        onAttachToContext(context);
    }

    /**
     * Deprecated on API 23 but still necessary for pre API 23 devices.
     */
    @SuppressWarnings("deprecation")
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            onAttachToContext(activity);
        }
    }

    /**
     * Called when the fragment attaches to the context
     */
    protected void onAttachToContext(Context context) {
        if (!(context instanceof Callback)) {
            throw new IllegalStateException("Activity must implement callback interface.");
        }

        callback = (Callback) context;
    }

    private class MyListAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return DummyContent.ITEMS.size();
        }

        @Override
        public Object getItem(int position) {
            return DummyContent.ITEMS.get(position);
        }

        @Override
        public long getItemId(int position) {
            return DummyContent.ITEMS.get(position).id.hashCode();
        }

        @Override
        public View getView(int position, View convertView, ViewGroup container) {
            if (convertView == null) {
                convertView = LayoutInflater.from(getActivity()).inflate(R.layout.list_item_article, container, false);
            }

            final DummyContent.DummyItem item = (DummyContent.DummyItem) getItem(position);
            ((TextView) convertView.findViewById(R.id.article_title)).setText(item.title);
            ((TextView) convertView.findViewById(R.id.article_subtitle)).setText(item.author);
            final ImageView img = (ImageView) convertView.findViewById(R.id.thumbnail);
            Glide.with(getActivity()).load(item.photoId).asBitmap().into(new BitmapImageViewTarget(img) {
                @Override
                protected void setResource(Bitmap resource) {
                    RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(getActivity().getResources(), resource);
                    circularBitmapDrawable.setCircular(true);
                    img.setImageDrawable(circularBitmapDrawable);
                }
            });

            return convertView;
        }
    }

    public PortfolioListFragment() {
    }
}


问:
Spring REST return byte[] like field in response
I have a class ProductItem

```<code>@Data
public class ProductItem {
  private String name;
  private String description;
  private byte[] image;
}
</code>```

And Spring rest method:

```<code>@GetMapping(value = "/test")
private ResponseEntity<ProductItem> findProduct() {
    ProductItem i= service.getProductItem()
    return ResponseEntity.ok(i);
}
</code>```

How can I correctly return byte[] in  this class?

答:
You can base64 encode the byte[] to a String in you ProductItem's field

Or

You can add HttpServletReponse to your method and write the byte[] in the response's OutputStream. In this case no need to return ResponseEntity.

Body:
I have a class ProductItem

@Data
public class ProductItem {
  private String name;
  private String description;
  private byte[] image;
}

And Spring rest method:

@GetMapping(value = "/test")
private ResponseEntity<ProductItem> findProduct() {
    ProductItem i= service.getProductItem()
    return ResponseEntity.ok(i);
}

How can I correctly return byte[] in  this class?


问:
How to use Python with pandas exporting Data to GeoJSON for Google Map
I am doing a project about web crawler.

I will got some point location include (Name, longitude, latitude)

Then point all of them in Google Map(use Google Map API)

First

I got some data from the website API. -- (300points locaiton)

Then use Python pandas DataFrame to export Json File

```<code>df = pd.DataFrame(total, columns=['name','lat', 'lng'])
df['lat'] = pd.to_numeric(df['lat'])
df['lng'] = pd.to_numeric(df['lng'])

jsonFile = df.to_json(orient='records')
with open('map.json','w') as f:
    f.write(jsonFile)
</code>```

json structure look like this

```<code>{
"name":"臺中女中",
"lat":24.13604,
"lng":120.6778
}
</code>```

So here is the problem:

How can I import those of point to Google Map use Google Map API

I've tried to read the Google Map API Document, it just tell me to use

```<code>map.data.loadGeoJson('map.json');
</code>```

Finally i got wrong. and the Error Message

```<code>uncaught exception: InvalidValueError: not a Feature or FeatureCollection
</code>```

Is Google Map API only support GeoJson?

How can I change my json file to the GeoJson?

or how can I modify my json file that can use in Google Map API.

Thank you very much.

答:
How can I change my json file to the GeoJson?

You could use geojson

Here's an example:

Import:

```<code>import json
import pandas as pd
from geojson import Feature, FeatureCollection, Point
</code>```

DataFrame:

```<code>df = pd.DataFrame([{'name': '臺中女中', 'lat': 24.13604, 'lng': 120.6778}])
</code>```

Converting to geojson:

```<code># columns used for constructing geojson object
features = df.apply(
    lambda row: Feature(geometry=Point((float(row['lng']), float(row['lat'])))),
    axis=1).tolist()

# all the other columns used as properties
properties = df.drop(['lat', 'lng'], axis=1).to_dict('records')

# whole geojson object
feature_collection = FeatureCollection(features=features, properties=properties)
</code>```

Then you could save your geojson file:

```<code>with open('/path/to/your/file.geojson', 'w', encoding='utf-8') as f:
    json.dump(feature_collection, f, ensure_ascii=False)
</code>```

Body:
I am doing a project about web crawler.

I will got some point location include (Name, longitude, latitude)

Then point all of them in Google Map(use Google Map API)

First

I got some data from the website API. -- (300points locaiton)

Then use Python pandas DataFrame to export Json File

df = pd.DataFrame(total, columns=['name','lat', 'lng'])
df['lat'] = pd.to_numeric(df['lat'])
df['lng'] = pd.to_numeric(df['lng'])

jsonFile = df.to_json(orient='records')
with open('map.json','w') as f:
    f.write(jsonFile)

json structure look like this

{
"name":"臺中女中",
"lat":24.13604,
"lng":120.6778
}

So here is the problem:

How can I import those of point to Google Map use Google Map API

I've tried to read the Google Map API Document, it just tell me to use

map.data.loadGeoJson('map.json');

Finally i got wrong. and the Error Message

uncaught exception: InvalidValueError: not a Feature or FeatureCollection

Is Google Map API only support GeoJson?

How can I change my json file to the GeoJson?

or how can I modify my json file that can use in Google Map API.

Thank you very much.

Body:
How can I change my json file to the GeoJson?

You could use geojson

Here's an example:

Import:

import json
import pandas as pd
from geojson import Feature, FeatureCollection, Point

DataFrame:

df = pd.DataFrame([{'name': '臺中女中', 'lat': 24.13604, 'lng': 120.6778}])

Converting to geojson:

# columns used for constructing geojson object
features = df.apply(
    lambda row: Feature(geometry=Point((float(row['lng']), float(row['lat'])))),
    axis=1).tolist()

# all the other columns used as properties
properties = df.drop(['lat', 'lng'], axis=1).to_dict('records')

# whole geojson object
feature_collection = FeatureCollection(features=features, properties=properties)

Then you could save your geojson file:

with open('/path/to/your/file.geojson', 'w', encoding='utf-8') as f:
    json.dump(feature_collection, f, ensure_ascii=False)


问:
Bootstrap Products horizontally like eCommerce store
I want my Products horizontally like in the attached image but when i add products in my page it shows in vertical format but i want horizontal like attached like eCommerce product page picture here</p>

答:
All you need to set correct grid structure of bootstrap here

Based on your picture there needs to set the grids of 3 columns.
You can get idea for this from bootstrap official website: https://getbootstrap.com/docs/3.3/css/#grid

Here is the basic code for the grids, which you can modify further.

1st Grid

2nd Grid

3rd Grid

```

Body:
All you need to set correct grid structure of bootstrap here

Based on your picture there needs to set the grids of 3 columns.
You can get idea for this from bootstrap official website: https://getbootstrap.com/docs/3.3/css/#grid

Here is the basic code for the grids, which you can modify further.

<div class="row">
  <div class="col-lg-4 col-md-4 col-sm-4">1st Grid</div>
  <div class="col-lg-4 col-md-4 col-sm-4">2nd Grid</div>
  <div class="col-lg-4 col-md-4 col-sm-4">3rd Grid</div>
</div>


问:
Does nhibernate work with .net core?
I tried to download the package with nuget in .net core 1.0 console application but it failed to build.
Is there any version work with .net core and it is cross platform or not?</p>

答:
NHibernate has moved from JIRA to GitHub some time ago.

You can now track the progress in these items:

GitHub issue: NH-3807 - Support for .NET Core 2.0

Current pull request: NH-3807 - Support for .NET Core 2.0

Title: Does nhibernate work with .net core?


问:
What are these controller parameters in controller file?
I am turning over my head to understand AngularJS. I am unable to make sense of this. Online guides are only basic as far as I have seen.

app.register.controller("viewTests", [
  "$scope",
  "$modal",
  "$http",
  "$route",
  "pinesNotifications",
  "$location",
  "$route",
  "$routeParams",
  "$timeout",
  "$modal",
  function (
    $scope,
    $modal,
    $http,
    $route,
    pinesNotifications,
    $location,
    $routeParams,
    $timeout
  ){
```

Please explain to me:

How do they work and interact?

Is the parameter order important?

答:
The convention that you are using is one of the convention that can be used with angular. In that particular convention, you are injecting the dependency as well as using them for that particular controller, and order of the dependencies matters for that, else your use of dependency won't work as you are expecting.

```<code>app.register.controller('viewTests',function($scope, $modal,$http,$route,){

})
</code>```

In the convention above, the order does not matter. I believe i have answered your number 2 question.

Now, for number 1 question. The working logic is similar to normal require that you use in javascript, however in angularjs you have a main module where you inject all your dependencies, and access them on your controllers. There are certain dependencies that are readily available in angularjs such as $scope, $http. However, if there are any external plugins that you require, then you inject it in your main module. For example: In order to use $state in the controller you would require the 'ui.router' which you inject as follows.

```<code>var app = angular.module('yourAppName', ['ui.router']);

app.config(function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/home');

    $stateProvider

        // HOME STATES AND NESTED VIEWS ========================================
        .state('home', {
            url: '/home',
            templateUrl: 'partial-home.html'
        })

        // ABOUT PAGE AND MULTIPLE NAMED VIEWS =================================
        .state('about', {
            // we'll get to this in a bit
        });

});
app.register.controller('viewTests',function($scope, $state){

})
</code>```

Likewise, you inject the necessary dependency and use only necessary dependencies in your controller as well.

ContentLicense: CC BY-SA 4.0

Body:
I am turning over my head to understand AngularJS. I am unable to make sense of this. Online guides are only basic as far as I have seen.

app.register.controller("viewTests", [
  "$scope",
  "$modal",
  "$http",
  "$route",
  "pinesNotifications",
  "$location",
  "$route",
  "$routeParams",
  "$timeout",
  "$modal",
  function (
    $scope,
    $modal,
    $http,
    $route,
    pinesNotifications,
    $location,
    $routeParams,
    $timeout
  ){

Please explain to me:

How do they work and interact?

Is the parameter order important?

Body:
The convention that you are using is one of the convention that can be used with angular. In that particular convention, you are injecting the dependency as well as using them for that particular controller, and order of the dependencies matters for that, else your use of dependency won't work as you are expecting.

app.register.controller('viewTests',function($scope, $modal,$http,$route,){

})

In the convention above, the order does not matter. I believe i have answered your number 2 question.

Now, for number 1 question. The working logic is similar to normal require that you use in javascript, however in angularjs you have a main module where you inject all your dependencies, and access them on your controllers. There are certain dependencies that are readily available in angularjs such as $scope, $http. However, if there are any external plugins that you require, then you inject it in your main module. For example: In order to use $state in the controller you would require the 'ui.router' which you inject as follows.

var app = angular.module('yourAppName', ['ui.router']);

app.config(function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/home');

    $stateProvider

        // HOME STATES AND NESTED VIEWS ========================================
        .state('home', {
            url: '/home',
            templateUrl: 'partial-home.html'
        })

        // ABOUT PAGE AND MULTIPLE NAMED VIEWS =================================
        .state('about', {
            // we'll get to this in a bit
        });

});
app.register.controller('viewTests',function($scope, $state){

})

Likewise, you inject the necessary dependency and use only necessary dependencies in your controller as well.


问:
blank "DOMNodeList" reading XML via Xpath
I am trying to read the value of "SIM" via the below PHP code via the XML given below, but for some reason it gives me a blank "DOMNodeList" Any idea what i am doing wrong here ? I wanted to set that element as

```<code><ns1:SIM old="8902"> 000000 </SIM>
</code>```

How do i do that, because I am trying with below code to find it but it seems output is "DOMNodeList" empty.

```<code>$xpath = new DOMXPath($doc);
$xpath->registerNamespace('ns1', 'http://www.example.com/WSG/ec/');
$result = $xpath->query("/ns1:ModifySIMRequest/ns1:ServiceProfile/ns1:Primary/ns1:SIM");
        foreach ($result AS $node) {
            var_dump($node);
            echo $node->nodeValue;
        }
</code>```

XML in $doc is

```<code><?xml version="1.0"?>
<ns1:ModifySIMRequest xmlns:ns1="http://www.example.com/WSG/ec/">
  <ns1:ServiceProfile>
    <ns1:Speech>
      <ns1:MSN>33808089</ns1:MSN>
      <ns1:AccountNumber>8989895</ns1:AccountNumber>
    </ns1:Speech>
    <ns1:Primary action="mod">
      <ns1:BillingOption>dsdsd</ns1:BillingOption>
      <ns1:SIM old="8902"/>
    </ns1:Primary>
  </ns1:ServiceProfile>
</ns1:ModifySIMRequest>
</code>```

答:
The text content/node value of the element {http://www.example.com/WSG/ec/}SIM is empty. If you want to fetch the attribute here are two ways. You can use DOM methods to read the attribute values or extend the Xpath expression to fetch the attribute node. If you fetch the attribute you can even cast it into a string in the Xpath expression directly.

```<code>$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXPath($document);
$xpath->registerNamespace('ec', 'http://www.example.com/WSG/ec/');

$result = $xpath->evaluate("/ec:ModifySIMRequest/ec:ServiceProfile/ec:Primary/ec:SIM");
foreach ($result AS $node) {
  // use the DOM method to fetch the attribute
  var_dump($node->getAttribute('old'));
}

// fetch the attribute node using Xpath
$result = $xpath->evaluate("/ec:ModifySIMRequest/ec:ServiceProfile/ec:Primary/ec:SIM/@old");
foreach ($result AS $node) {
  var_dump($node->textContent);
}

var_dump(
  // fetch the value of the first matching attribute as a string
  $xpath->evaluate("string(/ec:ModifySIMRequest/ec:ServiceProfile/ec:Primary/ec:SIM/@old)")
);
</code>```

Note: The namespace alias/prefix does not need to match the alias in the document. You can use a more meaningful one.

Body:
I am trying to read the value of "SIM" via the below PHP code via the XML given below, but for some reason it gives me a blank "DOMNodeList" Any idea what i am doing wrong here ? I wanted to set that element as

<ns1:SIM old="8902"> 000000 </SIM>

How do i do that, because I am trying with below code to find it but it seems output is "DOMNodeList" empty.

$xpath = new DOMXPath($doc);
$xpath->registerNamespace('ns1', 'http://www.example.com/WSG/ec/');
$result = $xpath->query("/ns1:ModifySIMRequest/ns1:ServiceProfile/ns1:Primary/ns1:SIM");
        foreach ($result AS $node) {
            var_dump($node);
            echo $node->nodeValue;
        }

XML in $doc is

<?xml version="1.0"?>
<ns1:ModifySIMRequest xmlns:ns1="http://www.example.com/WSG/ec/">
  <ns1:ServiceProfile>
    <ns1:Speech>
      <ns1:MSN>33808089</ns1:MSN>
      <ns1:AccountNumber>8989895</ns1:AccountNumber>
    </ns1:Speech>
    <ns1:Primary action="mod">
      <ns1:BillingOption>dsdsd</ns1:BillingOption>
      <ns1:SIM old="8902"/>
    </ns1:Primary>
  </ns1:ServiceProfile>
</ns1:ModifySIMRequest>

Body:
The text content/node value of the element {http://www.example.com/WSG/ec/}SIM is empty. If you want to fetch the attribute here are two ways. You can use DOM methods to read the attribute values or extend the Xpath expression to fetch the attribute node. If you fetch the attribute you can even cast it into a string in the Xpath expression directly.

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXPath($document);
$xpath->registerNamespace('ec', 'http://www.example.com/WSG/ec/');

$result = $xpath->evaluate("/ec:ModifySIMRequest/ec:ServiceProfile/ec:Primary/ec:SIM");
foreach ($result AS $node) {
  // use the DOM method to fetch the attribute
  var_dump($node->getAttribute('old'));
}

// fetch the attribute node using Xpath
$result = $xpath->evaluate("/ec:ModifySIMRequest/ec:ServiceProfile/ec:Primary/ec:SIM/@old");
foreach ($result AS $node) {
  var_dump($node->textContent);
}

var_dump(
  // fetch the value of the first matching attribute as a string
  $xpath->evaluate("string(/ec:ModifySIMRequest/ec:ServiceProfile/ec:Primary/ec:SIM/@old)")
);

Note: The namespace alias/prefix does not need to match the alias in the document. You can use a more meaningful one.


问:
Babel - decorator of decorated class properties is called before instantiating class
Excuse me for creating a new question, I was not able to find a question addressing this matter.

I am having difficulties testing my dependency injection using mocha and experimental es6+ decorators transpiled using babel. The class property decorator is being called before it should've been.

injection.test.js (mocha test, using --require babel-register)

```<code>import * as DependencyInjection from '../build/decorators/DependencyInjection';

@DependencyInjection.Injectable(service => service.injected = true)
class SampleService {

    property = 'default';

    constructor(property, ...data) {
        this.property = property || this.property;
    }
}

class Dependant {

    /** @type {SampleService} */
    @DependencyInjection.Inject(SampleService)
    sampleService;
}

describe('dependency injection', () => {

    describe('is decoratored as injectable', () => {
        it('should be injectable', done => done(SampleService.injectable ? void 0 : new Error('Injectable is not set')));

        it('should contain a predicate', done => done(SampleService.predicate ? void 0 : new Error('Predicate is not set')));
    });

    describe('inject injectable', () => {
        it ('should inject the injectable provider', done => {
            const dependant = new Dependant();

            done(!!dependant.sampleService ? void 0 : new Error('Injectable provider was not injected'));
        })
    });
});
</code>```

When running the test, the decorated class is transformed as inteded. However, the sampleService property of the instance of Dependant, created in the second test, is undefined.

The decorator in question should be called/invoked once an instance of the class is being created, but the decorator is called when the class is defined and the property is decorated. The expected behaviour is maintained when using TypeScript.

Below I've listed the (simplified) decorators and my babel configuration.

.babelrc

```<code>{
    "presets": [
        "env",
        "stage-0",
        "es2017"
    ],
    "plugins": [
        "syntax-decorators",
        "transform-decorators-legacy",
        ["transform-runtime", {
            "polyfill": false,
            "regenerator": true
        }]
    ]
}
</code>```

exported decorator Inject (targeting class property):

```<code>exports.Inject = (typeFunction, ...data) => {
    return function (target, propertyName) {
        try {
            const injected = target[propertyName] = new typeFunction(data);
            if ('predicate' in typeFunction && typeof typeFunction.predicate === 'function') {
                typeFunction.predicate(injected);
            }
        }
        catch (err) {
            throw new Error(err.message || err);
        }
    };
};
</code>```

exported decorator Injectable (targeting class):

```<code>exports.Injectable = (predicate) => {
    return function (target) {
        const provider = target;
        provider.injectable = true;
        if (predicate && typeof predicate === 'function') {
            provider.predicate = predicate;
        }
    };
};
</code>```

答:
I still haven't found the leading cause why it creates a new instance of the class when decorating the class property. However, I have found a working solution to my problem. Within mocha, using --require babel-register and the legacy decorator plugin, the class property decorator makes use of the PropertyDescriptor. Changing the simplified Inject decorator to the following has solved my problem of not instantiating my decorated class property.

```<code>exports.Inject = (typeFunction, ...data) => {
    return function (target, propertyName, descriptor) {
        let value = null;
        try {
            const injected = value = target[propertyName] = new typeFunction(...data);
            if ('predicate' in typeFunction && typeof typeFunction.predicate === 'function') {
                typeFunction.predicate(injected);
            }
        }
        catch (err) {
            throw new Error(err.message || err);
        }
        if (descriptor) {
            delete descriptor.initializer;
            delete descriptor.writable;
            descriptor.value = value;
        }
    };
};
</code>```

Deleting the writable property is neccesary.

The following tests...

```<code>const assert = require('assert');
const chai = require('chai');

import * as DependencyInjection from '../build/decorators/DependencyInjection';

@DependencyInjection.Injectable(service => service.injected = true)
class SampleService {

    property = 'default';

    constructor(property, ...data) {
        this.property = property || this.property;
    }
}

class Dependant {

    /** @type {SampleService} */
    @DependencyInjection.Inject(SampleService)
    sampleService;
}

class Dependant2 {

    /** @type {SampleService} */
    @DependencyInjection.Inject(SampleService, 'overloaded')
    sampleService;
}

describe('dependency injection', () => {

    describe('is decoratored as injectable', () => {
        it('should be injectable', done => done(SampleService.injectable ? void 0 : new Error('Injectable is not set')));

        it('should contain a predicate', done => done(SampleService.predicate ? void 0 : new Error('Predicate is not set')));
    });

    describe('inject at decorated class property', () => {
        it('should inject the injectable provider at the decorated property', () => {
            const dependant = new Dependant();

            chai.expect(dependant.sampleService).to.be.instanceof(SampleService, 'Injectable provider was not injected');

            chai.assert.isTrue(dependant.sampleService.injected, 'The predicate of the injectable service was not set');

            chai.expect(dependant.sampleService.property).to.equal('default', 'The initial value of \'property\' was not \'default\'');
        });

        it('should inject the injectable provider with overloaded constructor arguments at the decorated property', () => {
            const dependant = new Dependant2();

            chai.expect(dependant.sampleService).to.be.instanceOf(SampleService, 'Injectable provider was not injected');

            chai.assert.isTrue(dependant.sampleService.injected, 'The predicate of the injectable service was not set');

            chai.expect(dependant.sampleService.property).to.equal('overloaded', 'The value of \'property\' was not overloaded');
        });
    });

    describe('inject at manual target and property', () => {
        it('should inject the injectable provider at the targeting value', () => {
            const inject = DependencyInjection.Inject(SampleService);

            const target = {};

            let err = null;
            try {
                inject(target, 'service');
            } catch (e) {
                err = e;
            }

            chai.assert.isNull(err, 'Expected injection to pass');

            chai.expect(target.service).to.be.instanceOf(SampleService, 'Injectable provider was not injected');

            chai.assert.isTrue(target.service.injected, 'The predicate of the injectable service was not set');

            chai.expect(target.service.property).to.equal('default', 'The initial value of \'property\' was not \'default\'');
        });

        it('should inject the injectable provider with overloaded constructor arguments at the targeting value', () => {
            const inject = DependencyInjection.Inject(SampleService, 'overloaded');

            const target = {};

            let err = null;
            try {
                inject(target, 'service');
            } catch (e) {
                err = e;
            }

            chai.assert.isNull(err, 'Expected injection to pass');

            chai.expect(target.service).to.be.instanceOf(SampleService, 'Injectable provider was not injected');

            chai.assert.isTrue(target.service.injected, 'The predicate of the injectable service was not set');

            chai.expect(target.service.property).to.equal('overloaded', 'The value of \'property\' was not overloaded');
        });

        it('should not inject anything at the targeting value', () => {
            const inject = DependencyInjection.Inject();

            const target = {};

            let err = null;
            try {
                inject(target, 'service');
            } catch (e) {
                err = e;
            }

            chai.expect(err).to.be.instanceof(Error);

            chai.assert.notExists(target.service);
        });
    });
});
</code>```

...output the following result:

```<code>  dependency injection
    is decoratored as injectable
      √ should be injectable
      √ should contain a predicate
    inject at decorated class property
      √ should inject the injectable provider at the decorated property
      √ should inject the injectable provider with overloaded constructor arguments at the decorated property
    inject at manual target and property
      √ should inject the injectable provider at the targeting value
      √ should inject the injectable provider with overloaded constructor arguments at the targeting value
      √ should not inject anything at the targeting value

  7 passing (29ms)
</code>```

Body:
Excuse me for creating a new question, I was not able to find a question addressing this matter.

I am having difficulties testing my dependency injection using mocha and experimental es6+ decorators transpiled using babel. The class property decorator is being called before it should've been.

injection.test.js (mocha test, using --require babel-register)

import * as DependencyInjection from '../build/decorators/DependencyInjection';

@DependencyInjection.Injectable(service => service.injected = true)
class SampleService {

    property = 'default';

    constructor(property, ...data) {
        this.property = property || this.property;
    }
}

class Dependant {

    /** @type {SampleService} */
    @DependencyInjection.Inject(SampleService)
    sampleService;
}

describe('dependency injection', () => {

    describe('is decoratored as injectable', () => {
        it('should be injectable', done => done(SampleService.injectable ? void 0 : new Error('Injectable is not set')));

        it('should contain a predicate', done => done(SampleService.predicate ? void 0 : new Error('Predicate is not set')));
    });

    describe('inject injectable', () => {
        it ('should inject the injectable provider', done => {
            const dependant = new Dependant();

            done(!!dependant.sampleService ? void 0 : new Error('Injectable provider was not injected'));
        })
    });
});

When running the test, the decorated class is transformed as inteded. However, the sampleService property of the instance of Dependant, created in the second test, is undefined.

The decorator in question should be called/invoked once an instance of the class is being created, but the decorator is called when the class is defined and the property is decorated. The expected behaviour is maintained when using TypeScript.

Below I've listed the (simplified) decorators and my babel configuration.

.babelrc

{
    "presets": [
        "env",
        "stage-0",
        "es2017"
    ],
    "plugins": [
        "syntax-decorators",
        "transform-decorators-legacy",
        ["transform-runtime", {
            "polyfill": false,
            "regenerator": true
        }]
    ]
}

exported decorator Inject (targeting class property):

exports.Inject = (typeFunction, ...data) => {
    return function (target, propertyName) {
        try {
            const injected = target[propertyName] = new typeFunction(data);
            if ('predicate' in typeFunction && typeof typeFunction.predicate === 'function') {
                typeFunction.predicate(injected);
            }
        }
        catch (err) {
            throw new Error(err.message || err);
        }
    };
};

exported decorator Injectable (targeting class):

exports.Injectable = (predicate) => {
    return function (target) {
        const provider = target;
        provider.injectable = true;
        if (predicate && typeof predicate === 'function') {
            provider.predicate = predicate;
        }
    };
};

Body:
I still haven't found the leading cause why it creates a new instance of the class when decorating the class property. However, I have found a working solution to my problem. Within mocha, using --require babel-register and the legacy decorator plugin, the class property decorator makes use of the PropertyDescriptor. Changing the simplified Inject decorator to the following has solved my problem of not instantiating my decorated class property.

exports.Inject = (typeFunction, ...data) => {
    return function (target, propertyName, descriptor) {
        let value = null;
        try {
            const injected = value = target[propertyName] = new typeFunction(...data);
            if ('predicate' in typeFunction && typeof typeFunction.predicate === 'function') {
                typeFunction.predicate(injected);
            }
        }
        catch (err) {
            throw new Error(err.message || err);
        }
        if (descriptor) {
            delete descriptor.initializer;
            delete descriptor.writable;
            descriptor.value = value;
        }
    };
};

Deleting the writable property is neccesary.

The following tests...

const assert = require('assert');
const chai = require('chai');

import * as DependencyInjection from '../build/decorators/DependencyInjection';

@DependencyInjection.Injectable(service => service.injected = true)
class SampleService {

    property = 'default';

    constructor(property, ...data) {
        this.property = property || this.property;
    }
}

class Dependant {

    /** @type {SampleService} */
    @DependencyInjection.Inject(SampleService)
    sampleService;
}

class Dependant2 {

    /** @type {SampleService} */
    @DependencyInjection.Inject(SampleService, 'overloaded')
    sampleService;
}

describe('dependency injection', () => {

    describe('is decoratored as injectable', () => {
        it('should be injectable', done => done(SampleService.injectable ? void 0 : new Error('Injectable is not set')));

        it('should contain a predicate', done => done(SampleService.predicate ? void 0 : new Error('Predicate is not set')));
    });

    describe('inject at decorated class property', () => {
        it('should inject the injectable provider at the decorated property', () => {
            const dependant = new Dependant();

            chai.expect(dependant.sampleService).to.be.instanceof(SampleService, 'Injectable provider was not injected');

            chai.assert.isTrue(dependant.sampleService.injected, 'The predicate of the injectable service was not set');

            chai.expect(dependant.sampleService.property).to.equal('default', 'The initial value of \'property\' was not \'default\'');
        });

        it('should inject the injectable provider with overloaded constructor arguments at the decorated property', () => {
            const dependant = new Dependant2();

            chai.expect(dependant.sampleService).to.be.instanceOf(SampleService, 'Injectable provider was not injected');

            chai.assert.isTrue(dependant.sampleService.injected, 'The predicate of the injectable service was not set');

            chai.expect(dependant.sampleService.property).to.equal('overloaded', 'The value of \'property\' was not overloaded');
        });
    });

    describe('inject at manual target and property', () => {
        it('should inject the injectable provider at the targeting value', () => {
            const inject = DependencyInjection.Inject(SampleService);

            const target = {};

            let err = null;
            try {
                inject(target, 'service');
            } catch (e) {
                err = e;
            }

            chai.assert.isNull(err, 'Expected injection to pass');

            chai.expect(target.service).to.be.instanceOf(SampleService, 'Injectable provider was not injected');

            chai.assert.isTrue(target.service.injected, 'The predicate of the injectable service was not set');

            chai.expect(target.service.property).to.equal('default', 'The initial value of \'property\' was not \'default\'');
        });

        it('should inject the injectable provider with overloaded constructor arguments at the targeting value', () => {
            const inject = DependencyInjection.Inject(SampleService, 'overloaded');

            const target = {};

            let err = null;
            try {
                inject(target, 'service');
            } catch (e) {
                err = e;
            }

            chai.assert.isNull(err, 'Expected injection to pass');

            chai.expect(target.service).to.be.instanceOf(SampleService, 'Injectable provider was not injected');

            chai.assert.isTrue(target.service.injected, 'The predicate of the injectable service was not set');

            chai.expect(target.service.property).to.equal('overloaded', 'The value of \'property\' was not overloaded');
        });

        it('should not inject anything at the targeting value', () => {
            const inject = DependencyInjection.Inject();

            const target = {};

            let err = null;
            try {
                inject(target, 'service');
            } catch (e) {
                err = e;
            }

            chai.expect(err).to.be.instanceof(Error);

            chai.assert.notExists(target.service);
        });
    });
});

...output the following result:

  dependency injection
    is decoratored as injectable
      √ should be injectable
      √ should contain a predicate
    inject at decorated class property
      √ should inject the injectable provider at the decorated property
      √ should inject the injectable provider with overloaded constructor arguments at the decorated property
    inject at manual target and property
      √ should inject the injectable provider at the targeting value
      √ should inject the injectable provider with overloaded constructor arguments at the targeting value
      √ should not inject anything at the targeting value

  7 passing (29ms)


问:
Erroneous Data explorer Azure batch -> python SDK uploads escaped json?
I'm using PyMongo (Python 3.6) to interface with a MongoDB API connected to a DocumentDB which is hosted on Azure. When updating existing _ids in the mongo DB I get the, apparently visual, error that my updated json (bson?) has been escaped. This happens in the Azure Data explorer. See picture.

The results when I query the database via the client though seem to be valid and in working order. The code fragment I use to upload the data looks as follows:

```<code>def upsert_data(self, collection: str, data: Any):
    bulk_updates = []
    coll = self._database[collection]

    for item in data:
        bulk_updates.append(
            UpdateOne(
                {"_id": ObjectId(item.pop("_id"))},
                {"$set": item}))

    try:
        coll.bulk_write(bulk_updates)
    except BulkWriteError as bwe:
        pprint.pprint(bwe.details)
</code>```

The self._database[collection] is a client created in the init.

The structure of the item (type: dict) roughly looks like:

```<code>   {
       'varA': 0,
       'varB': 12,
       'varC': [
           {'var2': 23},
           {'var2': 24}]
    }
</code>```

Is there anyone that could tell me if I'm doing something wrong? This is the solution I came up with after reading documentation. I'm fairly new at this. Any input would be much appreciated!

Thanks in advance!

答:
I'm not sure what your so-called json escaped meaning. Be covered up or the content is emptied? Your screenshot doesn't look complete either.

I follow your code to try to bulk-update data and it works fine.

Please refer to the snippet code as below:

```<code>import pymongo
from pymongo import UpdateOne

uri = "your connect string"
client = pymongo.MongoClient(uri)

bulk_updates = []

for doc in coll.find({}):
    bulk_updates.append(UpdateOne({'_id': doc.get('_id')},{"$set": {"test":"add"}}, upsert=False))

print(bulk_updates)

db.coll.bulk_write(bulk_updates)

print("update success ")
</code>```

Update Documents

For more Operations you can use with the bulk_write method here is the documentation link: http://api.mongodb.com/python/current/api/pymongo/operations.html

Body:
I'm using PyMongo (Python 3.6) to interface with a MongoDB API connected to a DocumentDB which is hosted on Azure. When updating existing _ids in the mongo DB I get the, apparently visual, error that my updated json (bson?) has been escaped. This happens in the Azure Data explorer. See picture.

The results when I query the database via the client though seem to be valid and in working order. The code fragment I use to upload the data looks as follows:

def upsert_data(self, collection: str, data: Any):
    bulk_updates = []
    coll = self._database[collection]

    for item in data:
        bulk_updates.append(
            UpdateOne(
                {"_id": ObjectId(item.pop("_id"))},
                {"$set": item}))

    try:
        coll.bulk_write(bulk_updates)
    except BulkWriteError as bwe:
        pprint.pprint(bwe.details)

The self._database[collection] is a client created in the init.

The structure of the item (type: dict) roughly looks like:

   {
       'varA': 0,
       'varB': 12,
       'varC': [
           {'var2': 23},
           {'var2': 24}]
    }

Is there anyone that could tell me if I'm doing something wrong? This is the solution I came up with after reading documentation. I'm fairly new at this. Any input would be much appreciated!

Thanks in advance!

Body:
I'm not sure what your so-called json escaped meaning. Be covered up or the content is emptied? Your screenshot doesn't look complete either.

I follow your code to try to bulk-update data and it works fine.

Please refer to the snippet code as below:

import pymongo
from pymongo import UpdateOne

uri = "your connect string"
client = pymongo.MongoClient(uri)

bulk_updates = []

for doc in coll.find({}):
    bulk_updates.append(UpdateOne({'_id': doc.get('_id')},{"$set": {"test":"add"}}, upsert=False))

print(bulk_updates)

db.coll.bulk_write(bulk_updates)

print("update success ")

Update Documents

For more Operations you can use with the bulk_write method here is the documentation link: http://api.mongodb.com/python/current/api/pymongo/operations.html